@selkirk-systems/selkirk-utils 1.0.2 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +12 -0
- package/dist/utils/ArrayUtils.js +48 -0
- package/dist/utils/CacheUtils.js +15 -0
- package/dist/utils/DateUtils.js +73 -0
- package/dist/utils/EntityUtils.js +28 -0
- package/dist/utils/EnvUtils.js +53 -0
- package/dist/utils/FetchUtils.js +70 -0
- package/dist/utils/IncidentUtils.js +19 -0
- package/dist/utils/LayerUtils.js +6 -0
- package/dist/utils/ListUtils.js +33 -0
- package/dist/utils/MapUtils.js +140 -0
- package/dist/utils/NumberUtils.js +13 -0
- package/dist/utils/ObjUtils.js +39 -0
- package/lib/index.js +12 -0
- package/lib/utils/ArrayUtils.js +98 -0
- package/lib/utils/CacheUtils.js +25 -0
- package/lib/utils/DateUtils.js +86 -0
- package/lib/utils/EntityUtils.js +48 -0
- package/lib/utils/EnvUtils.js +88 -0
- package/lib/utils/FetchUtils.js +68 -0
- package/lib/utils/IncidentUtils.js +26 -0
- package/lib/utils/LayerUtils.js +7 -0
- package/lib/utils/ListUtils.js +56 -0
- package/lib/utils/MapUtils.js +194 -0
- package/lib/utils/NumberUtils.js +22 -0
- package/lib/utils/ObjUtils.js +75 -0
- package/package.json +2 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const withPromiseCache = ( fn, cacheFn = () => { } ) => {
|
|
2
|
+
|
|
3
|
+
const cacheMap = {};
|
|
4
|
+
|
|
5
|
+
return ( ...args ) => {
|
|
6
|
+
|
|
7
|
+
const cache = cacheFn( ...args );
|
|
8
|
+
const cacheId = args.join( ":" );
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
if ( cache ) {
|
|
12
|
+
return cache;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if ( cacheMap.hasOwnProperty( cacheId ) ) return cacheMap[cacheId];
|
|
16
|
+
|
|
17
|
+
cacheMap[cacheId] = fn( ...args ).finally( () => {
|
|
18
|
+
|
|
19
|
+
delete cacheMap[cacheId];
|
|
20
|
+
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
return cacheMap[cacheId];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { format } from "date-fns"
|
|
2
|
+
|
|
3
|
+
export const formatDate = ( timestamp, formatStr, COMMON_DATE_FORMAT ) => {
|
|
4
|
+
|
|
5
|
+
if ( timestamp === null || timestamp === undefined ) return '';
|
|
6
|
+
|
|
7
|
+
return format( timestamp, formatStr || COMMON_DATE_FORMAT )
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const formatYearlessColumnDate = ( value, offsetDays ) => {
|
|
13
|
+
if(offsetDays != undefined){
|
|
14
|
+
value += offsetDays * 1000 * 60 * 60 * 24;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return format( new Date( value ), "MMM dd" );
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const formatColumnDate = ( data, value ) => {
|
|
22
|
+
|
|
23
|
+
return format( new Date( value ), "MMM dd, yyyy" );
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
export const formateDateAndTime = ( timestamp ) => {
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
return format( timestamp, "MMM dd, yyyy@HH:mm" );
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const startOfCurrentYear = () => {
|
|
37
|
+
|
|
38
|
+
return new Date( new Date().getFullYear(), 0, 1 ).getTime();
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const lastYearTimestamp = () => {
|
|
43
|
+
|
|
44
|
+
var d = new Date( new Date().getFullYear() - 1, 0, 1 );
|
|
45
|
+
d.setHours( 0, 0, 0, 0 );
|
|
46
|
+
return d.getTime();
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const DateToTimestamp = ( date ) => date.getTime();
|
|
51
|
+
export const TimestampToDate = ( timestamp ) => new Date( timestamp );
|
|
52
|
+
|
|
53
|
+
export const getTodaysDate = () => {
|
|
54
|
+
let localeOptions = { month: 'short', day: 'numeric', year: 'numeric' };
|
|
55
|
+
return new Date().toLocaleDateString( 'en-US', localeOptions );
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const getYesterdaysDate = () => {
|
|
59
|
+
let localeOptions = { month: 'short', day: 'numeric', year: 'numeric' };
|
|
60
|
+
return new Date( new Date().setDate( new Date().getDate() - 1 ) ).toLocaleDateString( 'en-US', localeOptions );
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const convertTimestampToDateString = ( date ) => {
|
|
64
|
+
let localeOptions = { month: 'short', day: 'numeric', year: 'numeric' };
|
|
65
|
+
return new Date( date ).toLocaleDateString( 'en-US', localeOptions );
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const convertTimestampToTimeString = ( date ) => {
|
|
69
|
+
let localeOptions = { month: 'numeric', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit' };
|
|
70
|
+
return new Date( date ).toLocaleTimeString( 'en-US', localeOptions );
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const getCurrentDateString = ( creationTimestamp ) => {
|
|
74
|
+
const today = getTodaysDate();
|
|
75
|
+
const yesterday = getYesterdaysDate();
|
|
76
|
+
const commentDate = convertTimestampToDateString( creationTimestamp );
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
if ( commentDate === today ) {
|
|
80
|
+
return 'Today';
|
|
81
|
+
} else if ( commentDate === yesterday ) {
|
|
82
|
+
return 'Yesterday';
|
|
83
|
+
} else {
|
|
84
|
+
return commentDate;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export const getEntityLinkId = ( obj, propName ) => {
|
|
4
|
+
|
|
5
|
+
if ( !obj._links ) return null;
|
|
6
|
+
|
|
7
|
+
const href = obj._links[propName]?.href || "";
|
|
8
|
+
|
|
9
|
+
return getIdFromHref( href );
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const getEntityLinkTitle = ( obj, propName ) => {
|
|
14
|
+
|
|
15
|
+
if ( !obj._links ) return null;
|
|
16
|
+
|
|
17
|
+
return obj._links[propName]?.title;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const createLinkObj = ( obj ) => {
|
|
22
|
+
return {
|
|
23
|
+
href: obj?._links?.self?.href,
|
|
24
|
+
title: obj?.displayLabel
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const getIdFromHref = ( href ) => {
|
|
29
|
+
|
|
30
|
+
const hrefArray = href.split( "/" );
|
|
31
|
+
|
|
32
|
+
return hrefArray.length ? hrefArray[hrefArray.length - 1] : null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
export const getEntityTypeByObj = (obj)=>{
|
|
37
|
+
const reg = /.com(:\d+)?\/(.+?)\//g;
|
|
38
|
+
|
|
39
|
+
if(!obj?._links?.self?.href) return null;
|
|
40
|
+
|
|
41
|
+
const match = reg.exec(obj._links.self.href);
|
|
42
|
+
|
|
43
|
+
if(!match.length || match.length<2){
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return match[2];
|
|
48
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createPortal } from "react-dom";
|
|
2
|
+
|
|
3
|
+
export const getEnvironmentVariable = ( name ) => {
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
return process.env[`REACT_APP_${name}`];
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const createUrlParams = ( params, existingParams ) => {
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const searchParams = existingParams ? existingParams : new URLSearchParams();
|
|
15
|
+
|
|
16
|
+
for ( var prop in params ) {
|
|
17
|
+
if ( !params.hasOwnProperty( prop ) || params[prop] === undefined || params[prop] === null ) continue;
|
|
18
|
+
|
|
19
|
+
if ( Array.isArray( params[prop] ) ) {
|
|
20
|
+
|
|
21
|
+
if ( prop === "sort" ) {
|
|
22
|
+
searchParams.delete( "sort" );
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
for ( let i = 0; i < params[prop].length; i++ ) {
|
|
26
|
+
const e = params[prop][i];
|
|
27
|
+
if ( searchParams.has( prop ) && prop !== "sort" ) {
|
|
28
|
+
searchParams.set( prop, e );
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
searchParams.append( prop, e );
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if ( searchParams.has( prop ) ) {
|
|
38
|
+
searchParams.set( prop, params[prop] );
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
searchParams.append( prop, params[prop] );
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
return searchParams;
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//TODO: DRY these up
|
|
52
|
+
export const createGISURL = ( basePath,path="",params )=>{
|
|
53
|
+
const baseUrl = `${window.location.origin}${window.baseURL}/gis/`;
|
|
54
|
+
const url = new URL( `${baseUrl}${basePath}${path !== "" ? "/" + path : path}` );
|
|
55
|
+
|
|
56
|
+
if ( !params ) return url;
|
|
57
|
+
|
|
58
|
+
url.search = createUrlParams( params );
|
|
59
|
+
|
|
60
|
+
return url;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const createProxiedURL = ( basePath, path = "", params ) => {
|
|
64
|
+
|
|
65
|
+
const baseUrl = `${window.location.origin}${window.baseURL||''}/p/`;
|
|
66
|
+
const url = new URL( `${baseUrl}${basePath}${path !== "" ? "/" + path : path}` );
|
|
67
|
+
|
|
68
|
+
if ( !params ) return url;
|
|
69
|
+
|
|
70
|
+
url.search = createUrlParams( params );
|
|
71
|
+
|
|
72
|
+
return url;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
export const createApiURL = ( basePath, path = "", qParams ) => {
|
|
77
|
+
|
|
78
|
+
const baseUrl = `${window.location.origin}${window.baseURL}/api`;
|
|
79
|
+
const url = new URL( `${baseUrl}${basePath}${path !== "" ? "/" + path : path}` );
|
|
80
|
+
|
|
81
|
+
if ( !qParams ) return url;
|
|
82
|
+
|
|
83
|
+
url.search = createUrlParams( qParams );
|
|
84
|
+
|
|
85
|
+
return url;
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { dispatch } from "@selkirk-systems/state-management";
|
|
2
|
+
|
|
3
|
+
export const serializeResponse = ( [response, isAbort] ) => {
|
|
4
|
+
//Is any status is outside 200 - 299 it is not ok
|
|
5
|
+
if ( response.status.code < 200 || response.status.code >= 300 || isAbort ) {
|
|
6
|
+
return [response, isAbort];
|
|
7
|
+
}
|
|
8
|
+
if ( Array.isArray( response.data ) ) {
|
|
9
|
+
return [response, isAbort];
|
|
10
|
+
}
|
|
11
|
+
if ( response.data._embedded ) {
|
|
12
|
+
response.data.items = response.data._embedded[[Object.keys( response.data._embedded )[0]]];
|
|
13
|
+
delete response.data._embedded;
|
|
14
|
+
return [response, isAbort];
|
|
15
|
+
} else {
|
|
16
|
+
response.data.items = [];
|
|
17
|
+
}
|
|
18
|
+
return [response, isAbort];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const blockOnError = fn => ([err,data,results])=>{
|
|
22
|
+
if(err){
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn([data,results]);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const serializeAndRespondWith = (action,payload={}) => {
|
|
30
|
+
/**
|
|
31
|
+
* Callback function for a Fetch call then()
|
|
32
|
+
* @name serializeCallbackFn
|
|
33
|
+
* @method
|
|
34
|
+
*
|
|
35
|
+
* @param {array} array - Response array return by the Fetch library
|
|
36
|
+
* @param {object} array.response - data returned from the Fetch call
|
|
37
|
+
* @param {boolean} array.isAbort - was the fetch call aborted for some reason.
|
|
38
|
+
*
|
|
39
|
+
* @returns {array<object,boolean>}
|
|
40
|
+
*/
|
|
41
|
+
return ([response, isAbort]) => {
|
|
42
|
+
//Is any status is outside 200 - 299 it is not ok
|
|
43
|
+
if (response.status.code < 200 || response.status.code >= 300 || isAbort) {
|
|
44
|
+
return [response, isAbort];
|
|
45
|
+
}
|
|
46
|
+
let data = {};
|
|
47
|
+
if (Array.isArray(response.data)) {
|
|
48
|
+
dispatch(action, {
|
|
49
|
+
items: response.data
|
|
50
|
+
});
|
|
51
|
+
return [response, isAbort];
|
|
52
|
+
} else {
|
|
53
|
+
data = {
|
|
54
|
+
...response.data
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (data._embedded) {
|
|
58
|
+
data.items = data._embedded[[Object.keys(data._embedded)[0]]];
|
|
59
|
+
delete data._embedded;
|
|
60
|
+
dispatch(action, {...data,...payload});
|
|
61
|
+
return [response, isAbort];
|
|
62
|
+
} else {
|
|
63
|
+
data.items = [];
|
|
64
|
+
}
|
|
65
|
+
dispatch(action, {...data,...payload});
|
|
66
|
+
return [response, isAbort];
|
|
67
|
+
};
|
|
68
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const WILDFIRE_STATUS_PRIORITY = {
|
|
2
|
+
"OC":1,
|
|
3
|
+
"BH":2,
|
|
4
|
+
"UC":3,
|
|
5
|
+
"EX":4,
|
|
6
|
+
"TO":5
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getHighestPriorityStatus(clusterDataArray){
|
|
10
|
+
|
|
11
|
+
let status = null;
|
|
12
|
+
|
|
13
|
+
clusterDataArray.reduce(
|
|
14
|
+
(acc, loc) =>{
|
|
15
|
+
if( WILDFIRE_STATUS_PRIORITY[acc.status] < WILDFIRE_STATUS_PRIORITY[loc.status]){
|
|
16
|
+
status = acc.status
|
|
17
|
+
return acc;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
status = loc.status;
|
|
21
|
+
return loc;
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
return status;
|
|
26
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Return an array containing all descendants of the supplied parentId
|
|
4
|
+
*
|
|
5
|
+
* @param {Object[]} arrayOfLayers Flat Array of objects with a parentId
|
|
6
|
+
* @param {Object} parent Top level parent
|
|
7
|
+
* @param {function} idFn function that returns true if it should be a descendant
|
|
8
|
+
* @returns {Object[]}
|
|
9
|
+
*/
|
|
10
|
+
export const getAllDescendants = ( arrayOfLayers, parent, idFn ) => {
|
|
11
|
+
|
|
12
|
+
let ret = [];
|
|
13
|
+
|
|
14
|
+
for ( let i = 0; i < arrayOfLayers.length; i++ ) {
|
|
15
|
+
|
|
16
|
+
const layer = arrayOfLayers[i];
|
|
17
|
+
|
|
18
|
+
if ( idFn( layer, parent ) ) {
|
|
19
|
+
ret.push( layer );
|
|
20
|
+
ret = ret.concat( getAllDescendants( arrayOfLayers, layer, idFn ) )
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return ret;
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
export const getAllAncestors = ( arrayOfLayers, parent, idFn ) => {
|
|
32
|
+
|
|
33
|
+
let ret = [];
|
|
34
|
+
|
|
35
|
+
for ( let i = 0; i < arrayOfLayers.length; i++ ) {
|
|
36
|
+
|
|
37
|
+
const layer = arrayOfLayers[i];
|
|
38
|
+
|
|
39
|
+
if ( idFn( parent, layer ) ) {
|
|
40
|
+
ret.push( layer );
|
|
41
|
+
ret = ret.concat( getAllAncestors( arrayOfLayers, layer, idFn ) )
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return ret;
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
export function isParentLayer( list, layer ) {
|
|
53
|
+
|
|
54
|
+
return list.find( item => item.parentLayerId === layer.id );
|
|
55
|
+
|
|
56
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/* eslint-disable no-redeclare */
|
|
2
|
+
import * as numeral from "numeral";
|
|
3
|
+
import * as L from "leaflet";
|
|
4
|
+
|
|
5
|
+
const long =
|
|
6
|
+
/^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$/;
|
|
7
|
+
const lat =
|
|
8
|
+
/^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$/;
|
|
9
|
+
const latitude = (coordinate) => lat.test(coordinate);
|
|
10
|
+
const longitude = (coordinate) => long.test(coordinate);
|
|
11
|
+
const latLong = (lat, long) => latitude(lat) && longitude(long);
|
|
12
|
+
|
|
13
|
+
const validationLatitudeLongitude = {
|
|
14
|
+
latitude,
|
|
15
|
+
longitude,
|
|
16
|
+
latLong,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const boundContains = (bounds, arrayOfLayers) => {
|
|
20
|
+
return arrayOfLayers.filter((layer) => {
|
|
21
|
+
return bounds.contains(layer.getLatLng());
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const checkGeoFence = (point, polygon) => {
|
|
26
|
+
if (polygon[0] !== polygon[polygon.length - 1])
|
|
27
|
+
polygon[polygon.length] = polygon[0];
|
|
28
|
+
let j = 0;
|
|
29
|
+
let oddNodes = false;
|
|
30
|
+
let x = point[1];
|
|
31
|
+
let y = point[0];
|
|
32
|
+
let n = polygon.length;
|
|
33
|
+
for (let i = 0; i < n; i++) {
|
|
34
|
+
j++;
|
|
35
|
+
if (j === n) {
|
|
36
|
+
j = 0;
|
|
37
|
+
}
|
|
38
|
+
if (
|
|
39
|
+
(polygon[i][0] < y && polygon[j][0] >= y) ||
|
|
40
|
+
(polygon[j][0] < y && polygon[i][0] >= y)
|
|
41
|
+
) {
|
|
42
|
+
if (
|
|
43
|
+
polygon[i][1] +
|
|
44
|
+
((y - polygon[i][0]) / (polygon[j][0] - polygon[i][0])) *
|
|
45
|
+
(polygon[j][1] - polygon[i][1]) <
|
|
46
|
+
x
|
|
47
|
+
) {
|
|
48
|
+
oddNodes = !oddNodes;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return oddNodes;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const validateLatLng = (lat, lng) => {
|
|
56
|
+
return validationLatitudeLongitude.latLong(lat, lng);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const getMetersPerPixelAndZoom = (map, centerLatLng, size) => {
|
|
60
|
+
var pointC = map.latLngToContainerPoint(centerLatLng);
|
|
61
|
+
var pointX = [pointC.x + size, pointC.y]; // add one pixel to x
|
|
62
|
+
var pointY = [pointC.x, pointC.y + size]; // add one pixel to y
|
|
63
|
+
|
|
64
|
+
// convert containerpoints to latlng's
|
|
65
|
+
var latLngC = map.containerPointToLatLng(pointC);
|
|
66
|
+
var latLngX = map.containerPointToLatLng(pointX);
|
|
67
|
+
var latLngY = map.containerPointToLatLng(pointY);
|
|
68
|
+
|
|
69
|
+
var distanceX = latLngC.distanceTo(latLngX); // calculate distance between c and x (latitude)
|
|
70
|
+
var distanceY = latLngC.distanceTo(latLngY); // calculate distance between c and y (longitude)
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
x: distanceX,
|
|
74
|
+
y: distanceY,
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const leadZero = (num, padding) => {
|
|
79
|
+
var len = (parseInt(num) + "").length;
|
|
80
|
+
if (padding > len) {
|
|
81
|
+
return new Array(padding - len + 1).join("0") + num;
|
|
82
|
+
}
|
|
83
|
+
return num + "";
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const decimalToDecialDegrees = (dec) => {
|
|
87
|
+
return numeral(dec).format("0.000000");
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const decimalToDecimalMinutesSeconds = (dec) => {
|
|
91
|
+
if (dec === undefined || dec === null) return dec;
|
|
92
|
+
|
|
93
|
+
var sign = dec > 0 ? "" : "-",
|
|
94
|
+
dec = Math.abs(dec),
|
|
95
|
+
decRnd = Math.floor(dec);
|
|
96
|
+
|
|
97
|
+
const min = (dec - decRnd) * 60.0,
|
|
98
|
+
minRnd = Math.floor(min);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
sign +
|
|
102
|
+
decRnd +
|
|
103
|
+
" " +
|
|
104
|
+
leadZero(minRnd, 2) +
|
|
105
|
+
" " +
|
|
106
|
+
leadZero(numeral((min - minRnd) * 60.0).format("0.00"), 2)
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
export const decimalDegreeMinutesToDecimalDegrees = (strVal) => {
|
|
110
|
+
if (strVal === undefined || strVal === null) return strVal;
|
|
111
|
+
|
|
112
|
+
var dm = strVal.split(/\s/);
|
|
113
|
+
var dec = parseInt(dm[0]);
|
|
114
|
+
|
|
115
|
+
var sign = dec < 0 ? -1 : 1,
|
|
116
|
+
deg = Math.abs(dec),
|
|
117
|
+
mm = parseFloat(dm[1]) || 0;
|
|
118
|
+
return sign * (deg + mm / 60.0);
|
|
119
|
+
};
|
|
120
|
+
export const decimalToDecimalDegreeMinutes = (dec) => {
|
|
121
|
+
if (dec === undefined || dec === null) return dec;
|
|
122
|
+
|
|
123
|
+
var sign = dec > 0 ? "" : "-",
|
|
124
|
+
dec = Math.abs(dec),
|
|
125
|
+
decRnd = Math.floor(dec);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
sign +
|
|
129
|
+
decRnd +
|
|
130
|
+
"°" +
|
|
131
|
+
leadZero(numeral((dec - decRnd) * 60.0).format("0.0000"), 2)
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export const FORMAT = {
|
|
136
|
+
DDM: "DDM",
|
|
137
|
+
DD: "DD",
|
|
138
|
+
DMS: "DMS",
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const formatCoord = (dec, format) => {
|
|
142
|
+
switch (format) {
|
|
143
|
+
case FORMAT.DMS:
|
|
144
|
+
return decimalToDecimalMinutesSeconds(dec);
|
|
145
|
+
case FORMAT.DDM:
|
|
146
|
+
return decimalToDecimalDegreeMinutes(dec);
|
|
147
|
+
default:
|
|
148
|
+
return decimalToDecialDegrees(dec);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const getVerticalHeight =(percent)=>{
|
|
153
|
+
var h = Math.max(
|
|
154
|
+
document.documentElement.clientHeight,
|
|
155
|
+
window.innerHeight || 0
|
|
156
|
+
);
|
|
157
|
+
return (percent * h) / 100;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Feature array needs to include latitude and longitudes
|
|
162
|
+
*/
|
|
163
|
+
export const InBounds = (bounds,features)=>{
|
|
164
|
+
|
|
165
|
+
const inBoundsFeatures = [];
|
|
166
|
+
|
|
167
|
+
features.forEach(clusterGroup=>{
|
|
168
|
+
if(!clusterGroup.enabled) return;
|
|
169
|
+
const features = clusterGroup.features;
|
|
170
|
+
|
|
171
|
+
for (let i = 0; i < features.length; i++) {
|
|
172
|
+
const feature = features[i];
|
|
173
|
+
|
|
174
|
+
if(bounds.contains([feature.latitude,feature.longitude])){
|
|
175
|
+
inBoundsFeatures.push(feature);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
return inBoundsFeatures;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const getCircleBounds = (radius,center,map)=>{
|
|
185
|
+
const metresPerPixel = 40075016.686 * Math.abs(Math.cos(map.getCenter().lat * Math.PI/180)) / Math.pow(2, map.getZoom()+8);
|
|
186
|
+
const meters = radius * metresPerPixel;
|
|
187
|
+
|
|
188
|
+
const circle = L.circle(center,{radius:meters}).addTo(map);
|
|
189
|
+
const bounds = circle.getBounds();
|
|
190
|
+
circle.removeFrom(map);
|
|
191
|
+
|
|
192
|
+
return bounds;
|
|
193
|
+
|
|
194
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import numeral from "numeral";
|
|
2
|
+
|
|
3
|
+
export const convertTo0To1 = ( value ) => {
|
|
4
|
+
const OldRange = ( 100 - 0 )
|
|
5
|
+
const NewRange = ( 1 - 0 )
|
|
6
|
+
|
|
7
|
+
if ( value === null || value === undefined ) return value;
|
|
8
|
+
|
|
9
|
+
return ( ( ( value - 0 ) * NewRange ) / OldRange ) + 0
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const formatPhone = (value ) => {
|
|
14
|
+
|
|
15
|
+
return numeral( value ).format( '(NNN) NNN-NNNN' )
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
export const formatColumnCurrency = ( data, value ) => {
|
|
19
|
+
|
|
20
|
+
return numeral( value ).format( '$0,0.00' )
|
|
21
|
+
|
|
22
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/* eslint-disable no-self-compare */
|
|
2
|
+
function is( x, y ) {
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
if ( x === y ) {
|
|
6
|
+
|
|
7
|
+
return x !== 0 || y !== 0 || 1 / x === 1 / y
|
|
8
|
+
|
|
9
|
+
} else {
|
|
10
|
+
|
|
11
|
+
return x !== x && y !== y
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
const hasOwn = Object.prototype.hasOwnProperty;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export function shallowEqual( objA, objB ) {
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if ( is( objA, objB ) ) return true
|
|
24
|
+
|
|
25
|
+
if (
|
|
26
|
+
typeof objA !== 'object' ||
|
|
27
|
+
objA === null ||
|
|
28
|
+
typeof objB !== 'object' ||
|
|
29
|
+
objB === null
|
|
30
|
+
) {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const keysA = Object.keys( objA )
|
|
35
|
+
const keysB = Object.keys( objB )
|
|
36
|
+
|
|
37
|
+
if ( keysA.length !== keysB.length ) return false
|
|
38
|
+
|
|
39
|
+
for ( let i = 0; i < keysA.length; i++ ) {
|
|
40
|
+
|
|
41
|
+
if ( !hasOwn.call( objB, keysA[i] ) || !is( objA[keysA[i]], objB[keysA[i]] ) ) {
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return true
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
export const getType = ( type ) => {
|
|
54
|
+
return Object.prototype.toString.call( type );
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const isFunc = ( type ) => getType( type ) === "[object Function]";
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
export const getID = ( entity, prop ) => {
|
|
61
|
+
const match = entity[prop] || entity?._links[prop]?.href;
|
|
62
|
+
|
|
63
|
+
if ( !match ) return null;
|
|
64
|
+
|
|
65
|
+
if ( match.indexOf( "http" ) >= 0 ) {
|
|
66
|
+
|
|
67
|
+
const strArray = match.split( "/" );
|
|
68
|
+
return strArray[strArray.length - 1];
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const isEmptyObject = (obj)=>{
|
|
74
|
+
return Object.keys(obj).length === 0;
|
|
75
|
+
}
|