/* eslint-disable no-case-declarations */
/* eslint vars-on-top: 0, newline-after-var: 0, consistent-return:0, no-throw-literal:0 */
import Collection from 'ol/Collection'
import { asArray } from 'ol/color'
import Colorize from 'ol-ext/filter/Colorize'
import Texture from 'ol-ext/filter/Texture'
import Fold from 'ol-ext/filter/Fold'
/**
* Module de gestion des filtres de carte
* @module filter
*/
const libNamespace = 'filter'
const PRESET = {
grayscale: { operation: 'hue', color: [0, 0, 0, 1] },
invert: { operation: 'difference', color: [255, 255, 255, 1] },
sepia: { operation: 'color', color: [153, 102, 51, 0.6] },
}
class Filter {
constructor (viewer, options) {
viewer.FILTER_LOADED = true
this.ctx = viewer
// Collection des filtres sur la carte
this.filters_ = new Collection([], true)
this.customTexture_ = {}
this.customPreset_ = {}
Object.assign(this, options)
}
getFilter_ (id) {
return this.filters_.getArray().find(item => item.get('id') === id)
}
getFiltersId () {
return this.filters_.getArray().map(item => item.get('id'))
}
filterExist (id) {
return !!this.getFilter_(id)
}
getTexture_ (name) {
// TODO Vérifier l'obtention de Texture[name]
console.log('GET TEXTURE', name)
return this.customTexture_[name] || name
}
getPreset_ (name) {
return this.customPreset_[name] || PRESET[name]
}
addFilter (backgroundLayerId, id, options) {
console.log('ADD FILTER', { id, options })
options = options || {}
let filter
if (this.filterExist(id)) {
return false
}
switch (options.type) {
case 'colorize':
filter = new Colorize()
break
case 'texture':
filter = new Texture()
break
case 'fold':
filter = new Fold()
break
default:
return false
}
filter.set('id', id)
filter.set('type', options.type)
filter.set('backgroundLayerId', backgroundLayerId)
this.filters_.push(filter)
const bgLayer = this.ctx.commonLayer.getLayer(backgroundLayerId)
if (bgLayer) {
bgLayer.addFilter(filter)
}
this.setFilter(backgroundLayerId, id, options)
}
removeFilter (backgroundLayerId, id) {
const filter = this.getFilter_(id)
backgroundLayerId = backgroundLayerId || filter.get('backgroundLayerId')
const bgLayer = this.ctx.commonLayer.getLayer(backgroundLayerId)
if (filter && bgLayer) {
bgLayer.removeFilter(filter)
this.filters_.remove(filter)
}
}
setFilter (backgroundLayerId, id, options) {
options = options || {}
const filter = this.getFilter_(id)
console.log('SET FILTER', { id, options })
if (filter) {
// si on fait un setfilter d'un filter existant mais non présent sur le calque demandé, on l'ajoute au calque
// exemple analyse supprime le background a chaque maj de filter
backgroundLayerId = backgroundLayerId || filter.get('backgroundLayerId')
const bgLayer = this.ctx.commonLayer.getLayer(backgroundLayerId)
if (bgLayer && !bgLayer.getFilters().find((bgFilter) => bgFilter.get('id') === filter.get('id'))) {
bgLayer.addFilter(filter)
}
switch (filter.get('type')) {
case 'fold':
if (options.fold === false) {
filter.set('active', false)
break
}
Object.keys(options).forEach(key => {
if (['fold', 'margin', 'padding', 'fsize'].includes(key)) {
filter.set(key, options[key])
}
})
filter.set('active', true)
break
case 'texture':
const opacity = typeof options.opacity === 'number'
? options.opacity
: filter.get('opacity')
const src = options.texture
// ndhe: a priori on ne pouvait pas enlever un effet de texture vu qu'on prenait soit le nouveau, soit l'existant..
// je laisse en commentaire au cas ou ce soit le comportement voulu et que j'ai introduit un bug..
// const src = this.getTexture_(options.texture || filter.get('texture'))
if (src) {
filter.setFilter({ src, opacity, rotateWithView: true })
// filter.set('texture', || filter.get('texture'))
filter.set('texture', options.texture)
filter.set('active', true)
} else {
filter.set('active', false)
}
break
case 'colorize':
if (options.preset) {
options = this.getPreset_(options.preset)
}
if (options && options.color) {
options.color = typeof options.color === 'string'
? asArray(options.color)
: options.color
options.color[3] = typeof options.intensity === 'number'
? options.intensity
: options.color[3]
filter.setFilter({
operation: options.operation,
color: options.color,
value: options.color[3],
})
filter.set('active', true)
} else {
filter.set('active', false)
}
break
}
}
}
}
// Permet d'etendre le module
export default function extendCoreLib (options) {
return function patch (viewer) {
const functions = { }
functions[libNamespace] = new Filter(viewer, options)
return Object.assign(viewer, functions)
}
}