import type { Map as MbMap , Layer as MbLayer } from '@kbn/mapbox-gl' ; import { ILayer } from '../../classes/layers/layer' ; export function getIsTextLayer ( mbLayer ) { if ( mbLayer . type !== 'symbol' ) { return false ; } const styleNames = [ ] ; if ( mbLayer . paint ) { styleNames . push ( ... Object . keys ( mbLayer . paint ) ) ; } if ( mbLayer . layout ) { styleNames . push ( ... Object . keys ( mbLayer . layout ) ) ; } return styleNames . some ( ( styleName ) => { return styleName . startsWith ( 'text-' ) ; } ) ; } export function isGlDrawLayer ( mbLayerId ) { return mbLayerId . startsWith ( 'gl-draw' ) ; } function doesMbLayerBelongToMapLayerAndClass ( mapLayer , mbLayer , layerClass ) { if ( ! mapLayer . ownsMbLayerId ( mbLayer . id ) ) { return false ; } if ( layerClass === LAYER_CLASS . ANY ) { return true ; } const isTextLayer = getIsTextLayer ( mbLayer ) ; return layerClass === LAYER_CLASS . LABEL ? isTextLayer : ! isTextLayer ; } enum LAYER_CLASS { ANY = 'ANY' , LABEL = 'LABEL' , NON_LABEL = 'NON_LABEL' } function moveMapLayer ( mbMap , mbLayers , mapLayer , layerClass , beneathMbLayerId ? ) { mbLayers . filter ( ( mbLayer ) => { return doesMbLayerBelongToMapLayerAndClass ( mapLayer , mbLayer , layerClass ) ; } ) . forEach ( ( mbLayer ) => { mbMap . moveLayer ( mbLayer . id , beneathMbLayerId ) ; } ) ; } function getBottomMbLayerId ( mbLayers , mapLayer , layerClass ) { const bottomMbLayer = mbLayers . find ( ( mbLayer ) => { return doesMbLayerBelongToMapLayerAndClass ( mapLayer , mbLayer , layerClass ) ; } ) ; return bottomMbLayer ? bottomMbLayer . id : undefined ; } function isLayerInOrder ( mbMap , mapLayer , layerClass , beneathMbLayerId ? ) { const mbLayers = mbMap . getStyle ( ) . layers ! ; if ( ! beneathMbLayerId ) { return doesMbLayerBelongToMapLayerAndClass ( mapLayer , mbLayers [ mbLayers . length - 1 ] , layerClass ) ; } let inMapLayerBlock = false ; let nextMbLayerId = null ; for ( let i = 0 ; i < mbLayers . length ; i ++ ) { if ( ! inMapLayerBlock ) { if ( doesMbLayerBelongToMapLayerAndClass ( mapLayer , mbLayers [ i ] , layerClass ) ) { inMapLayerBlock = true ; } } else { if ( ! doesMbLayerBelongToMapLayerAndClass ( mapLayer , mbLayers [ i ] , layerClass ) ) { nextMbLayerId = mbLayers [ i ] . id ; break ; } } } return nextMbLayerId === beneathMbLayerId ; } export function syncLayerOrder ( mbMap , spatialFiltersLayer , layerList ) { const mbLayers = mbMap . getStyle ( ) . layers ; if ( ! mbLayers || mbLayers . length === 0 ) { return ; } if ( ! isLayerInOrder ( mbMap , spatialFiltersLayer , LAYER_CLASS . ANY ) ) { moveMapLayer ( mbMap , mbLayers , spatialFiltersLayer , LAYER_CLASS . ANY ) ; } let beneathMbLayerId = getBottomMbLayerId ( mbLayers , spatialFiltersLayer , LAYER_CLASS . ANY ) ; const glDrawLayer = { ownsMbLayerId : ( mbLayerId ) => { return isGlDrawLayer ( mbLayerId ) ; } , } as unknown as ILayer ; moveMapLayer ( mbMap , mbLayers , glDrawLayer , LAYER_CLASS . ANY , beneathMbLayerId ) ; const glDrawBottomMbLayerId = getBottomMbLayerId ( mbLayers , glDrawLayer , LAYER_CLASS . ANY ) ; if ( glDrawBottomMbLayerId ) { beneathMbLayerId = glDrawBottomMbLayerId ; } [ ... layerList ] . reverse ( ) . filter ( ( mapLayer ) => { return mapLayer . areLabelsOnTop ( ) ; } ) . forEach ( ( mapLayer ) => { if ( ! isLayerInOrder ( mbMap , mapLayer , LAYER_CLASS . LABEL , beneathMbLayerId ) ) { moveMapLayer ( mbMap , mbLayers , mapLayer , LAYER_CLASS . LABEL , beneathMbLayerId ) ; } const bottomMbLayerId = getBottomMbLayerId ( mbLayers , mapLayer , LAYER_CLASS . LABEL ) ; if ( bottomMbLayerId ) beneathMbLayerId = bottomMbLayerId ; } ) ; [ ... layerList ] . reverse ( ) . forEach ( ( mapLayer ) => { const layerClass = mapLayer . areLabelsOnTop ( ) ? LAYER_CLASS . NON_LABEL : LAYER_CLASS . ANY ; if ( ! isLayerInOrder ( mbMap , mapLayer , layerClass , beneathMbLayerId ) ) { moveMapLayer ( mbMap , mbLayers , mapLayer , layerClass , beneathMbLayerId ) ; } const bottomMbLayerId = getBottomMbLayerId ( mbLayers , mapLayer , layerClass ) ; if ( bottomMbLayerId ) beneathMbLayerId = bottomMbLayerId ; } ) ; }