import { HttpClient } from '@angular/common/http' ; import { Inject , Injectable } from '@angular/core' ; import { PLATFORM_ID } from '@angular/core' ; import { isPlatformBrowser } from '@angular/common' ; import { LineString , Polygon } from 'ol/geom' ; import { HsConfig } from './../../config.service' ; import { HsLogService } from './../../common/log/log.service' ; import { ProjectionLike , transform } from 'ol/proj' ; import { getArea , getDistance } from 'ol/sphere' ; export type Measurement = { size : number ; type : string ; unit : string ; } ; @ Injectable ( ) export class HsUtilsService { constructor ( public HsConfig , private http , private LogService , @ Inject ( PLATFORM_ID ) private platformId ) { } public param url param toEncoding returns proxify ( url , toEncoding ? ) { const laymanEp = this . HsConfig . datasources ?. find ( ( ep ) => ep . type == 'layman' ) ; if ( url . startsWith ( this . HsConfig . proxyPrefix ) || ( laymanEp && url . startsWith ( laymanEp . url ) ) ) { return url ; } if ( url . startsWith ( 'data:application' ) ) { return url ; } toEncoding = toEncoding === undefined ? true : toEncoding ; let outUrl = url ; const windowUrlPosition = url . indexOf ( window . location . origin ) ; if ( windowUrlPosition == - 1 || windowUrlPosition > 7 || this . getPortFromUrl ( url ) != this . getPortFromUrl ( window . location . origin ) ) { if ( this . HsConfig . useProxy === undefined || this . HsConfig . useProxy === true ) { outUrl = this . HsConfig . proxyPrefix || '/proxy/' ; if ( outUrl . indexOf ( 'hsproxy.cgi' ) > - 1 ) { if ( toEncoding && ( url . indexOf ( 'GetMap' ) == - 1 || url . indexOf ( 'GetFeatureInfo' ) > - 1 ) ) { outUrl += 'toEncoding=utf-8&' ; } outUrl = outUrl + 'url=' + encodeURIComponent ( url ) ; } else { outUrl += url ; } } } return outUrl ; } public param url returns async shortUrl ( url ) { if ( this . HsConfig . shortenUrl != undefined ) { return this . HsConfig . shortenUrl ( url ) ; } return await this . http . get ( this . proxify ( 'http://tinyurl.com/api-create.php?url=' + url ) , { responseType : 'text' , } ) . toPromise ( ) ; } param url returns getPortFromUrl ( url ) { if ( this . runningInBrowser ( ) ) { const link = document . createElement ( 'a' ) ; link . setAttribute ( 'href' , url ) ; if ( link . port == '' ) { if ( url . indexOf ( 'https://' ) === 0 ) { return '443' ; } if ( url . indexOf ( 'http://' ) === 0 ) { return '80' ; } } return link . port ; } } runningInBrowser ( ) { return isPlatformBrowser ( this . platformId ) ; } public param str returns getParamsFromUrl ( str ) { if ( typeof str !== 'string' ) { return { } ; } if ( str . includes ( '?' ) ) { str = str . substring ( str . indexOf ( '?' ) + 1 ) ; } else { return { } ; } return str . trim ( ) . split ( '&' ) . reduce ( ( ret , param ) => { if ( ! param ) { return ret ; } const parts = param . replace ( /\+/g , ' ' ) . split ( '=' ) ; let key = parts [ 0 ] ; let val = parts [ 1 ] ; key = decodeURIComponent ( key ) ; val = val === undefined ? null : decodeURIComponent ( val ) ; if ( ! ret . hasOwnProperty ( key ) ) { ret [ key ] = val ; } else if ( Array . isArray ( ret [ key ] ) ) { ret [ key ] . push ( val ) ; } else { ret [ key ] = [ ret [ key ] , val ] ; } return ret ; } , { } ) ; } public param { object } array returns paramsToURL ( array ) { const pairs = [ ] ; for ( const key in array ) { if ( array . hasOwnProperty ( key ) && array [ key ] !== undefined ) { pairs . push ( encodeURIComponent ( key ) + '=' + encodeURIComponent ( array [ key ] ) ) ; } } return pairs . join ( '&' ) ; } public param { element } newNode param { element } referenceNode insertAfter ( newNode , referenceNode ) { if ( newNode . length !== undefined && newNode . length > 0 ) { newNode = newNode [ 0 ] ; } referenceNode . parentNode . insertBefore ( newNode , referenceNode . nextSibling ) ; } public param { object } array returns paramsToURLWoEncode ( array ) { const pairs = [ ] ; for ( const key in array ) { if ( array . hasOwnProperty ( key ) ) { pairs . push ( key + '=' + array [ key ] ) ; } } return pairs . join ( '&' ) ; } public param { Function } func param wait param immediate param { object } context returns { Function } debounce ( func , wait , immediate , context ) { if ( context === undefined ) { context = this ; } return function ( ... args ) { const later = function ( ) { if ( ! immediate ) { func . apply ( context , args ) ; } context . timeout = null ; } ; const callNow = immediate && ! context . timeout ; clearTimeout ( context . timeout ) ; context . timeout = setTimeout ( later , wait ) ; if ( callNow ) { func . apply ( context , args ) ; } } ; } public returns generateUuid ( ) { return generateUuid ( ) ; } public param numOfSteps param step param opacity returns rainbow ( numOfSteps , step , opacity ) { let r , g , b ; const h = step / ( numOfSteps * 1.00000001 ) ; const i = ~ ~ ( h * 4 ) ; const f = h * 4 - i ; const q = 1 - f ; switch ( i % 4 ) { case 2 : ( r = f ) , ( g = 1 ) , ( b = 0 ) ; break ; case 0 : ( r = 0 ) , ( g = f ) , ( b = 1 ) ; break ; case 3 : ( r = 1 ) , ( g = q ) , ( b = 0 ) ; break ; case 1 : ( r = 0 ) , ( g = 1 ) , ( b = q ) ; break ; default : } const c = 'rgba(' + ~ ~ ( r * 235 ) + ',' + ~ ~ ( g * 235 ) + ',' + ~ ~ ( b * 235 ) + ', ' + opacity + ')' ; return c ; } param { object } from param { object ? } to returns structuredClone ( from , to ? ) { if ( from === null || typeof from !== 'object' ) { return from ; } if ( from . constructor != Object && from . constructor != Array ) { return from ; } if ( from . constructor == Date || from . constructor == RegExp || from . constructor == Function || from . constructor == String || from . constructor == Number || from . constructor == Boolean ) { return new from . constructor ( from ) ; } to = to || new from . constructor ( ) ; for ( const key in from ) { to [ key ] = typeof to [ key ] == 'undefined' ? this . structuredClone ( from [ key ] ) : to [ key ] ; } return to ; } param functionToCheck returns isFunction ( functionToCheck ) { return ( functionToCheck && { } . toString . call ( functionToCheck ) === '[object Function]' ) ; } param objectToCheck returns isPOJO ( objectToCheck ) { return ( objectToCheck && { } . toString . call ( objectToCheck ) === '[object Object]' ) ; } param { object } obj param { * } type returns instOf ( obj , type ) { return this . _instanceOf ( obj , type ) ; } private _instanceOf ( obj , klass ) { if ( obj === undefined || obj === null ) { return false ; } if ( this . isFunction ( klass ) ) { return obj instanceof klass ; } obj = Object . getPrototypeOf ( obj ) ; while ( obj !== null ) { if ( obj . constructor . name === klass ) { return true ; } obj = Object . getPrototypeOf ( obj ) ; } return false ; } param { Array < object > } dirtyArray param property returns { Array < object > } removeDuplicates ( dirtyArray , property ) { const propertyChain = property . split ( '.' ) ; const flatArray = [ ... dirtyArray ] ; for ( const prop of propertyChain ) { for ( const idx in flatArray ) { if ( flatArray [ idx ] === undefined ) { this . LogService . error ( `Property "${ prop }" not found in object.` ) ; return [ ] ; } flatArray [ idx ] = flatArray [ idx ] . get !== undefined ? flatArray [ idx ] . get ( prop ) : flatArray [ idx ] [ prop ] ; } } return dirtyArray . filter ( ( item , position ) => { let propertyValue = item ; for ( const prop of propertyChain ) { propertyValue = propertyValue . get !== undefined ? propertyValue . get ( prop ) : propertyValue [ prop ] ; } return flatArray . indexOf ( propertyValue ) === position ; } ) ; } hashCode ( s ) { let hash = 0 ; if ( s . length == 0 ) { return hash ; } for ( let i = 0 ; i < s . length ; i ++ ) { const char = s . charCodeAt ( i ) ; hash = ( hash << 5 ) - hash + char ; hash = hash & hash ; } return hash ; } public param target param search param replacement returns replaceAll ( target , search , replacement ) { return target . replace ( new RegExp ( search , 'g' ) , replacement ) ; } resolveEsModule ( module ) { if ( module . default ) { return module . default ; } else { return module ; } } public param target returns capitalizeFirstLetter ( target ) { return target . charAt ( 0 ) . toUpperCase ( ) + target . slice ( 1 ) ; } getAssetsPath ( ) { let assetsPath = this . HsConfig . assetsPath || '' ; assetsPath += assetsPath . endsWith ( '/' ) ? '' : '/' ; return assetsPath ; } getAjaxLoaderIcon ( ) { return this . getAssetsPath ( ) + 'img/ajax-loader.gif' ; } undefineEmptyString ( str ) { if ( str === undefined ) { return undefined ; } return str . trim ( ) != '' ? str : undefined ; } isOverflown ( element ) { return ( element . scrollHeight > element . clientHeight || element . scrollWidth > element . clientWidth ) ; } private param { LineString } line returns { Measurement } description formatLength ( line , sourceProj ) { let length = 0 ; const coordinates = line . getCoordinates ( ) ; for ( let i = 0 ; i < coordinates . length - 1 ; ++ i ) { const c1 = transform ( coordinates [ i ] , sourceProj , 'EPSG:4326' ) ; const c2 = transform ( coordinates [ i + 1 ] , sourceProj , 'EPSG:4326' ) ; length += getDistance ( c1 , c2 ) ; } const output = { size : length , type : 'Length' , unit : 'm' , } ; if ( length > 100 ) { output . size = Math . round ( ( length / 1000 ) * 100 ) / 100 ; output . unit = 'km' ; } else { output . size = Math . round ( length * 100 ) / 100 ; output . unit = 'm' ; } return output ; } private param { Polygon } polygon returns { object } description formatArea ( polygon , sourceProj ) { const area = Math . abs ( getArea ( polygon ) ) ; const output = { size : area , type : 'Area' , unit : 'm' , } ; if ( area > 10000 ) { output . size = Math . round ( ( area / 1000000 ) * 100 ) / 100 ; output . unit = 'km' ; } else { output . size = Math . round ( area * 100 ) / 100 ; output . unit = 'm' ; } return output ; } } export function generateUuid ( ) { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' . replace ( /[xy]/g , ( c ) => { const r = ( Math . random ( ) * 16 ) | 0 , v = c == 'x' ? r : ( r & 0x3 ) | 0x8 ; return v . toString ( 16 ) ; } ) ; }