UNPKG

@nextgis/utils

Version:
721 lines (679 loc) 21.6 kB
/** Bundle of @nextgis/utils; version: 3.0.0; author: NextGIS */ var Utils = (function (exports) { 'use strict'; function applyMixins(derivedCtor, baseCtors, opt = {}) { const derivedProperties = allProperties(derivedCtor.prototype); const replace = opt.replace !== void 0 ? opt.replace : true; baseCtors.forEach((baseCtor) => { Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { const isSomeProp = derivedProperties.indexOf(name) !== -1; if (!replace && !isSomeProp || replace) { const descriptor = Object.getOwnPropertyDescriptor( baseCtor.prototype, name ); if (descriptor) { Object.defineProperty(derivedCtor.prototype, name, descriptor); } } }); }); } function allProperties(obj) { return _allProperties(obj); } function _allProperties(obj, _props = []) { for (; obj !== null; obj = Object.getPrototypeOf(obj)) { const op = Object.getOwnPropertyNames(obj); for (let i = 0; i < op.length; i++) { if (_props.indexOf(op[i]) == -1) { _props.push(op[i]); } } } return _props; } function mixinProperties(derivedCtor, baseCtor, properties) { properties.forEach((name) => { const descriptor = Object.getOwnPropertyDescriptor( baseCtor.prototype, name ); if (descriptor) { Object.defineProperty(derivedCtor.prototype, name, descriptor); } }); } function arrayChunk(arr, size) { return Array.from( { length: Math.ceil(arr.length / size) }, (v, i) => arr.slice(i * size, i * size + size) ); } function arrayCompare(array1, array2) { array1 = Array.from(array1).sort(); array2 = Array.from(array2).sort(); return _arrayCompare(array1, array2); } function arrayCompareStrict(array1, array2) { array1 = Array.from(array1); array2 = Array.from(array2); return _arrayCompare(array1, array2); } function _arrayCompare(array1, array2) { return array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]; }); } function arrayUnique(arr) { return arr.filter((elem, pos, arr2) => { return arr2.indexOf(elem) == pos; }); } var __defProp$1 = Object.defineProperty; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "" , value); class Clipboard { constructor(text) { __publicField$1(this, "silent", true); if (text) { this.copy(text); } } static copy(text) { const clipboard = new Clipboard(); return clipboard.copy(text); } copy(text) { try { if (navigator.clipboard) { navigator.clipboard.writeText(text); } else if (window.clipboardData) { window.clipboardData.setData("text", text); } else { this.copyToClipboard(text); } if (!this.silent) console.log("Copied to Clipboard"); return true; } catch (e) { if (!this.silent) console.log("Please copy manually"); } return false; } copyToClipboard(text) { const input = document.createElement("input"); input.value = text; try { document.body.appendChild(input); this.copyNodeContentsToClipboard(input); } finally { document.body.removeChild(input); } } copyNodeContentsToClipboard(input) { input.select(); input.setSelectionRange(0, 99999); document.execCommand("copy"); } } function debounce(cb, wait = 10) { let timeoutId; function wrapper(...args) { wrapper.clear(); timeoutId = setTimeout(() => { timeoutId = null; cb.apply(this, args); }, wait); } wrapper.clear = function() { if (timeoutId) { clearTimeout(timeoutId); timeoutId = null; } }; return wrapper; } function DebounceDecorator(wait = 10) { return function(_target, key, descriptor) { return { configurable: true, enumerable: descriptor.enumerable, get: function getter() { Object.defineProperty(this, key, { configurable: true, enumerable: descriptor.enumerable, value: debounce(descriptor.value, wait) }); return this[key]; } }; }; } function debugLog(message) { { console.trace("DEBUG: " + message); return true; } } function deepmerge(target, src, mergeArray = false) { let target_ = target; const src_ = src; const array = Array.isArray(src_); let dst = array && [] || {}; if (array && Array.isArray(src_)) { if (mergeArray) { target_ = target_ || []; dst = dst.concat(target_); src_.forEach((e, i) => { if (typeof dst[i] === "undefined") { dst[i] = e; } else if (typeof e === "object") { dst[i] = deepmerge(target_[i], e, mergeArray); } else { if (target_.indexOf(e) === -1) { dst.push(e); } } }); } else { dst = src_; } } else { if (target_ && typeof target_ === "object") { Object.keys(target_).forEach(function(key) { dst[key] = target_[key]; }); } Object.keys(src_).forEach(function(key) { if (typeof src_[key] !== "object" || !src_[key]) { dst[key] = src_[key]; } else { if (typeof target_[key] === "object" && typeof src_[key] === "object") { dst[key] = deepmerge(target_[key], src_[key], mergeArray); } else { dst[key] = src_[key]; } } }); } return dst; } function defined(val) { return val !== void 0 && val !== null; } function full(val) { return typeof val === "string" ? !!val : defined(val); } function deprecatedMapClick(ev) { if (!ev.lngLat && ev.latLng) { debugLog("deprecated use of latLng in MapClickEvent, use lngLat instead"); const lat = ev.latLng.lat; const lng = ev.latLng.lng; ev.lngLat = [lng, lat]; } return ev; } function deprecatedWarn(message) { console.warn(`DEPRECATED WARN: ${message}`); } var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value); class Events { constructor(emitter) { this.emitter = emitter; __publicField(this, "_eventsStatus", {}); } setEventStatus(event, status) { this._eventsStatus[event] = status; } onLoad(event) { const events = Array.isArray(event) ? event : [event]; const promises = events.map( (x) => new Promise((res) => { if (this.getEventStatus(x)) { res(this); } else { const e = x; this.emitter.once(e, () => { this.setEventStatus(x, true); res(this); }); } }) ); return Promise.all(promises).then(() => this); } getEventStatus(event) { const _eventName = event; const status = this._eventsStatus[_eventName]; return status !== void 0 ? !!status : false; } } function flatten(data, opt = {}) { var _a; const flatArray = (_a = opt.flatArray) != null ? _a : true; const result = {}; function recurse(cur, prop) { if (Object(cur) !== cur) { result[prop] = cur; } else if (Array.isArray(cur) && flatArray) { const l = cur.length; for (let i = 0; i < l; i++) { recurse(cur[i], prop + "[" + i + "]"); } if (l === 0) result[prop] = []; } else { let isEmpty = true; for (const p in cur) { isEmpty = false; recurse(cur[p], prop ? prop + "." + p : p); } if (isEmpty && prop) result[prop] = {}; } } recurse(data, ""); return result; } function checkExtent(extent) { const [minLon, minLat, maxLon, maxLat] = extent; const isOrderValid = minLon < maxLon && minLat < maxLat; if (!isOrderValid) { console.log("Error: The extent coordinates are not in the correct order."); console.log( `Received extent: [${minLon}, ${minLat}, ${maxLon}, ${maxLat}]` ); const correctedExtent = [ Math.min(minLon, maxLon), Math.min(minLat, maxLat), Math.max(minLon, maxLon), Math.max(maxLat, minLat) ]; console.log(`Expected order: [${correctedExtent.join(", ")}]`); } const isValidLon = minLon >= -180 && maxLon <= 180; const isValidLat = minLat >= -90 && maxLat <= 90; if (!isValidLon || !isValidLat) { console.log( "Warning: The coordinates may not be within valid geographic ranges." ); } return isOrderValid && isValidLon && isValidLat; } const EARTHS_RADIUS = 6371; function degrees2meters(lng, lat) { lat = lat > 85.06 ? 85.06 : lat < -85.06 ? -85.06 : lat; const x = lng * 2003750834e-2 / 180; let y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180); y = y * 2003750834e-2 / 180; return [x, y]; } function meters2degrees(x, y) { const lon = x * 180 / 2003750834e-2; const lat = Math.atan(Math.exp(y * Math.PI / 2003750834e-2)) * 360 / Math.PI - 90; return [lon, lat]; } function degrees2Radian(deg) { return deg * Math.PI / 180; } function coordinatesCount(geojson) { let count = 0; eachCoordinates(geojson, () => count++); return count; } function getCoordinates(geojson) { const coordinates = []; eachCoordinates(geojson, (pos) => coordinates.push(pos)); return coordinates; } function eachCoordinates(geojson, cb) { eachGeometry(geojson, (geom) => { if ("coordinates" in geom) { if (geom.type === "Polygon" || geom.type === "MultiLineString") { for (const x of geom.coordinates) { x.forEach((y) => cb(y)); } } else if (geom.type === "MultiPolygon") { for (const x of geom.coordinates) { x.forEach((y) => y.forEach((z) => cb(z))); } } else if (geom.type === "Point") { cb(geom.coordinates); } else if (geom.type === "MultiPoint" || geom.type === "LineString") { for (const x of geom.coordinates) { cb(x); } } } return geom; }); } function getPolygons(geojson) { const polygons = []; eachGeometry(geojson, (geom) => { if ("coordinates" in geom) { if (geom.type === "Polygon") { geom.coordinates.forEach((x) => polygons.push(x)); } else if (geom.type === "MultiPolygon") { for (const x of geom.coordinates) { for (const y of x) { polygons.push(y); } } } } return geom; }); return polygons; } function eachGeometry(geojson, cb) { if (geojson.type === "FeatureCollection") { for (const f of geojson.features) { cb(f.geometry); } } else if (geojson.type === "Feature") { cb(geojson.geometry); } else if ("coordinates" in geojson) { cb(geojson); } } function latLngToLngLatArray(latLng) { return [latLng.lng, latLng.lat]; } function lngLatArrayToLatLng(coord) { return { lat: coord[1], lng: coord[0] }; } function getBoundsPolygon(b) { const polygon = { type: "Polygon", coordinates: [getBoundsCoordinates(b)] }; return polygon; } function getBoundsCoordinates(b) { const westNorth = [b[0], b[1]]; const eastNorth = [b[2], b[1]]; const eastSouth = [b[2], b[3]]; const westSouth = [b[0], b[3]]; return [westNorth, eastNorth, eastSouth, westSouth, westNorth]; } function getBoundsFeature(b) { const feature = { type: "Feature", properties: {}, geometry: getBoundsPolygon(b) }; return feature; } const d2r$1 = Math.PI / 180; const r2d$1 = 180 / Math.PI; function getCirclePolygonCoordinates(lng, lat, radius = 10, points = 6) { const rlat = radius / EARTHS_RADIUS * r2d$1; const rlng = rlat / Math.cos(lat * d2r$1); const extp = []; for (let i = 0; i < points + 1; i++) { const theta = Math.PI * (i / (points / 2)); const ex = lng + rlng * Math.cos(theta); const ey = lat + rlat * Math.sin(theta); extp.push([ex, ey]); } return extp; } function getCircleFeature(lng, lat, radius = 10, points = 6) { const polygon = getCirclePolygonCoordinates(lng, lat, radius, points); const feature = { type: "Feature", properties: {}, geometry: { type: "Polygon", coordinates: [polygon] } }; return feature; } function getIdentifyRadius(center, zoom, pixelRadius) { pixelRadius = pixelRadius != null ? pixelRadius : 10; const metresPerPixel = 40075016686e-3 * Math.abs(Math.cos(center[1] * 180 / Math.PI)) / Math.pow(2, zoom + 8); const radius = pixelRadius * metresPerPixel * 5e-4; return radius; } const d2r = Math.PI / 180; const r2d = 180 / Math.PI; function getSquarePolygonCoordinates(lng, lat, halfSideLength = 10) { const rlat = halfSideLength / EARTHS_RADIUS * r2d; const rlng = rlat / Math.cos(lat * d2r); const topLeft = [lng - rlng, lat + rlat]; const topRight = [lng + rlng, lat + rlat]; const bottomRight = [lng + rlng, lat - rlat]; const bottomLeft = [lng - rlng, lat - rlat]; return [topLeft, topRight, bottomRight, bottomLeft, topLeft]; } function isLngLatBoundsArray(array) { return Array.isArray(array) && array.length === 4 && array.every((x) => typeof x === "number"); } function round(val, toFixed) { const n = toFixed ? Number("1e+" + toFixed) : 1; return Math.round((val + Number.EPSILON) * n) / n; } function objectAssign(target, ...sources) { for (const source of sources) { for (const prop of Object.getOwnPropertyNames(source)) { target[prop] = source[prop]; } } } function isEqual(a, b, o, p) { if (a instanceof Array) { if (!(b instanceof Array)) return false; return b.sort().join("") === a.sort().join(""); } else if (a instanceof Date) { if (!(b instanceof Date)) return false; return "" + a === "" + b; } else if (a instanceof Function) { if (!(b instanceof Function)) return false; } else if (a instanceof Object) { if (!(b instanceof Object)) return false; if (a === o) { return b === p; } else { return objectDeepEqual(a, b); } } return a === b; } function objectDeepEqual(o, p) { const keysO = Object.keys(o).sort(); const keysP = Object.keys(p).sort(); if (keysO.length !== keysP.length) return false; if (keysO.join("") !== keysP.join("")) return false; for (let i = 0; i < keysO.length; i++) { const oVal = o[keysO[i]]; const pVal = p[keysP[i]]; if (!isEqual(oVal, pVal, o, p)) { return false; } } return true; } function objectRemoveEmpty(obj) { const newObj = {}; Object.keys(obj).forEach((key) => { if (!(obj[key] instanceof Array) && obj[key] === Object(obj[key])) { newObj[key] = objectRemoveEmpty(obj[key]); } else if (obj[key] !== void 0) { newObj[key] = obj[key]; } }); return newObj; } const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined"; const type = isBrowser ? "browser" : "node"; function getGlobalVariable() { if (isBrowser) { return window; } else { return global; } } function reEscape(s) { return s.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); } function sleep(delay = 0) { return new Promise((resolve) => setTimeout(resolve, delay)); } function camelize(text, separator = /[_.\- ]/) { const words = text.split(separator); let result = ""; for (let i = 0; i < words.length; i++) { const word = words[i]; const capitalizedWord = word.charAt(0).toUpperCase() + word.slice(1); result += capitalizedWord; } return result; } function capitalize(str) { str = String(str).toLowerCase(); return str[0].toUpperCase() + str.slice(1); } function numberWithSpaces(x) { const parts = x.toString().split("."); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, " "); return parts.join("."); } function isObjKey(obj, key) { if (typeof key === "string" || typeof key === "number") { return key in obj; } return false; } function keyInObj(obj, key) { return isObjKey(obj, key); } function isAnyJson(val) { if (typeof val === "boolean" || typeof val === "number" || typeof val === "string" || val === null) { return true; } else if (isObject(val)) { return isJsonMap(val); } else if (isArray(val)) { return isJsonArray(val); } return false; } function isJsonArray(val) { if (isArray(val)) { return val.every(isAnyJson); } return false; } function isJsonMap(val) { if (isObject(val)) { for (const i in val) { if (!isAnyJson(i)) { return false; } } } return false; } function isObject(val) { return Object.prototype.toString.call(val) === "[object Object]"; } function isArray(val) { return Object.prototype.toString.call(val) === "[object Array]"; } function unflatten(data) { if (Object(data) !== data || Array.isArray(data)) return data; const regex = /\.?([^.[\]]+)|\[(\d+)\]/g; const flat = {}; for (const p in data) { let cur = flat; let prop = ""; let m; while (m = regex.exec(p)) { cur = cur[prop] || (cur[prop] = m[2] ? [] : {}); prop = m[2] || m[1]; } cur[prop] = data[p]; } return flat[""] || flat; } function fixUrlStr(url) { return url.replace(/([^:]\/)\/+/g, "$1"); } function updateUrlParams(urlStr, params) { const url = new URL(urlStr); const searchParams = new URLSearchParams(url.search); Object.entries(params).forEach(([key, value]) => { if (value === void 0) { searchParams.delete(key); } else { searchParams.set(key, value); } }); searchParams.set("timestamp", String((/* @__PURE__ */ new Date()).getTime())); const newSearch = [...searchParams.entries()].map(([key, value]) => `${key}=${value}`).join("&"); return `${url.origin}${url.pathname}?${newSearch}`; } exports.Clipboard = Clipboard; exports.DebounceDecorator = DebounceDecorator; exports.EARTHS_RADIUS = EARTHS_RADIUS; exports.Events = Events; exports.allProperties = allProperties; exports.applyMixins = applyMixins; exports.arrayChunk = arrayChunk; exports.arrayCompare = arrayCompare; exports.arrayCompareStrict = arrayCompareStrict; exports.arrayUnique = arrayUnique; exports.camelize = camelize; exports.capitalize = capitalize; exports.checkExtent = checkExtent; exports.coordinatesCount = coordinatesCount; exports.debounce = debounce; exports.debugLog = debugLog; exports.deepmerge = deepmerge; exports.defined = defined; exports.degrees2Radian = degrees2Radian; exports.degrees2meters = degrees2meters; exports.deprecatedMapClick = deprecatedMapClick; exports.deprecatedWarn = deprecatedWarn; exports.eachCoordinates = eachCoordinates; exports.eachGeometry = eachGeometry; exports.fixUrlStr = fixUrlStr; exports.flatten = flatten; exports.full = full; exports.getBoundsCoordinates = getBoundsCoordinates; exports.getBoundsFeature = getBoundsFeature; exports.getBoundsPolygon = getBoundsPolygon; exports.getCircleFeature = getCircleFeature; exports.getCirclePolygonCoordinates = getCirclePolygonCoordinates; exports.getCoordinates = getCoordinates; exports.getGlobalVariable = getGlobalVariable; exports.getIdentifyRadius = getIdentifyRadius; exports.getPolygons = getPolygons; exports.getSquarePolygonCoordinates = getSquarePolygonCoordinates; exports.isAnyJson = isAnyJson; exports.isArray = isArray; exports.isBrowser = isBrowser; exports.isJsonArray = isJsonArray; exports.isJsonMap = isJsonMap; exports.isLngLatBoundsArray = isLngLatBoundsArray; exports.isObjKey = isObjKey; exports.isObject = isObject; exports.keyInObj = keyInObj; exports.latLngToLngLatArray = latLngToLngLatArray; exports.lngLatArrayToLatLng = lngLatArrayToLatLng; exports.meters2degrees = meters2degrees; exports.mixinProperties = mixinProperties; exports.numberWithSpaces = numberWithSpaces; exports.objectAssign = objectAssign; exports.objectDeepEqual = objectDeepEqual; exports.objectRemoveEmpty = objectRemoveEmpty; exports.reEscape = reEscape; exports.round = round; exports.sleep = sleep; exports.type = type; exports.unflatten = unflatten; exports.updateUrlParams = updateUrlParams; return exports; })({}); //# sourceMappingURL=utils.global.js.map