@nextgis/utils
Version:
Common development tools
721 lines (679 loc) • 21.6 kB
JavaScript
/** 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