components/layer/baseLayer.js

/*
 * @Author: wxq
 * @Date:   2017-07-26 11:22:13
 * @Last Modified by: wxq
 * @Last Modified time: 2018-05-07 14:50:13
 * @Email: 304861063@qq.com
 * @File Path: F:\work\hyMap\src\components\layer\baseLayer.js
 * @File Name: baseLayer.js
 * @Descript: 图层基类
 */
'use strict';

import baseUtil from '../../util/baseUtil';
import dataUtil from '../../util/dataUtil';

const turf = require('../../tools/turf');


class BaseLayer {
    LAYERKEY = 'hyLayer';

    /**
     *  初始化
     * @param {Object} options  参数
     * @param {Object} options.map  地图对象
     * @param {String} options.url  url地址
     * @param {Object} options.serie 数据对象
     * @param {String} options.layerType  图层类型
     */
    constructor({
                    map = undefined,
                    url = undefined,
                    serie = undefined,
                    layerType = ''
                } = {}) {

        this.url = url;
        this.map = map;
        this.id = (serie && serie.id && serie.id + '') || baseUtil.guid();
        this.name = serie && serie.name || '';
        this.layer = undefined;
        this.serie = serie;
        this.data;
        this.geojson = '';
        this.hoverEvent_enter = null;
        this.hoverEvent_leave = null;

    }

    /**
     * 获取id
     * @returns {string} id
     */
    getId() {

        return this.id;

    }

    /**
     * 获取map对象
     * @return {Map|null}
     */
    getMap() {

        if (this.map) {

            return this.map;

        }
        return null;

    }

    /**
     * 获取图层
     * @return {layer}   layer 图层
     */
    getLayer() {

        return this.layer;

    }


    /**
     * 获取数据
     * @return {Source}   source 数据源
     */
    getSource() {

        return this.map.getSource(this.id);

    }

    /**
     * 设置数据
     * @param  {JSON}   data 数据源
     */
    setSource(data) {

        this.map.getSource().setData(data);

    }

    /**
     *  设置Url地址
     * @param {String} url 地址
     */
    setUrl(url) {

        this.url = url;

    }

    /**
     * 获取url地址
     * @returns {String} url 地址
     */
    getUrl() {

        return this.url;

    }

    /**
     * 获取serie对象
     * @returns {undefined|*} serie
     */
    getSerie() {

        return this.serie;

    }

    /**
     * 增加数据
     * @param {Object} data source数据
     */
    addSource(data) {

        this.data = data;
        this.map.addSource(this.id, data);

    }

    /**
     * 增加图层
     * @param {JSON} json json数据
     */
    addLayer(json) {

        this.map.addLayer(json);
        this.map.fire('addLayer', {json, name: this.name, id: this.id});

    }

    /**
     * 初始化
     * @param {Object} serie 数据对象
     */
    init(serie) {

        if (this.map.realReady) {

            this.buildJson(serie);
            this.buildHoverEvent();

        } else {

            this.map.on('load', () => {

                this.map.realReady = true;
                this.buildJson(serie);
                this.buildHoverEvent();

            });

        }

    }

    /**
     * 构造图层
     * @param {String}id 唯一标识
     * @param {Object} style 样式Object
     * @param {boolean} isHover 是否为选中样式图层
     * @returns {{id: *, source: string|*, metadata: {_LKey: string}}}
     */
    buildLayer(id, style, isHover = false) {

        let json = {
            'id': id,
            'source': this.id,
            'metadata': {'_LKey': 'hyLayer'}
        };
        if (isHover) {

            json.id += '-hover';
            json['filter'] = ['==', 'id', ''];
            json.metadata['_LKey'] += '-hover';

        }
        return Object.assign(json, style);

    }

    /**
     * 构造高亮事件
     */
    buildHoverEvent() {


        // var popup = new mapboxgl.Popup({
        //     closeButton: false,
        //     closeOnClick: false
        // });

        this.hoverEvent_enter = e => {

            this.map.getCanvas().style.cursor = 'pointer';
            this.map.setFilter(this.id + '-hover', ['==', 'id', e.features[0].properties.id]);
            // popup.setLngLat(e.features[0].geometry.coordinates)
            //     .setHTML(e.features[0].properties.id)
            //     .addTo(this.map);

        };
        this.map.on('mouseenter', this.id, this.hoverEvent_enter);
        // this.map.on('mouseenter', this.id+'-hover', (e) => {
        //
        //
        //
        // });

        this.hoverEvent_leave = () => {

            this.map.getCanvas().style.cursor = '';
            this.map.setFilter(this.id + '-hover', ['==', 'id', '']);
            // popup.remove();

        };
        this.map.on('mouseleave', this.id + '-hover', this.hoverEvent_leave);


    }

    /**
     * 注册事件
     * @param {String} type 类型
     * @param {requestCallback} listener 监听方法
     */
    on(type, listener) {

        this.map.on(type, this.id + '-hover', listener);

    }

    /**
     * 移除注册事件
     * @param {String} type 类型
     * @param {requestCallback} listener 监听方法
     */
    off(type, listener) {

        this.map.off(type, this.id + '-hover', listener);

    }

    /**
     * 显示图层
     */
    show() {

        if (this.map.isStyleLoaded()) {

            this.map.setLayoutProperty(this.id, 'visibility', 'visible');

        } else {

            setTimeout(() => {

                this.show();

            }, 200);

        }

    }

    /**
     * 隐藏图层
     */
    hide() {

        if (this.map.isStyleLoaded()) {

            this.map.setLayoutProperty(this.id, 'visibility', 'none');

        } else {

            setTimeout(() => {

                this.hide();

            }, 200);

        }


    }
    
    /**
     * 更新数据
     * @param {*} serie 数据
     */
    update(serie = {}) {

        if (this.map.loaded()) {

            let dataObject = dataUtil.buildData(serie.data);
            let source = this.map.getSource(this.id);
            source && source.setData(dataObject.geojson.data);

        } else {

            setTimeout(() => {

                this.update(serie);

            }, 200);

        }


    }

    /**
     * 获取数据
     * @param {String} id 唯一标识
     * @returns {Object|null}
     */
    getFeatureById(id) {

        let feature;
        turf.featureEach(this.data.data, (fea) => {

            if (fea.properties.id === id) {

                feature = fea;
                feature.properties.layerid = this.id;

            }
            return;

        });
        // feature = this.map.querySourceFeatures(this.id, {
        //     filter: ['==', 'id', id]
        // });
        return feature;

    }

    /**
     * 根据属性获取数据
     * @param {String} key  属性
     * @param {String} value 值
     * @returns {Array}
     */
    getFeaturesByProperty(key, value) {

        let features = this.map.querySourceFeatures(this.id, {
            filter: ['==', key, value]
        });
        return features;

    }

    /**
     * 取消图层的hover监听
     */
    cancelHoverEvent() {

        if (this.map.isStyleLoaded()) {

            this.map.off('mouseenter', this.id, this.hoverEvent_enter);
            this.map.off('mouseleave', this.id+'-hover', this.hoverEvent_leave);

        }else{

            setTimeout(()=>{

                this.cancelHoverEvent();

            },200);

        }

    }

    /**
     * 销毁
     */
    dispose() {

        this.map.off('click', this.id, this.b);
        this.map.getLayer(this.id) && this.map.removeLayer(this.id);
        this.map.getLayer(this.id + '-hover') && this.map.removeLayer(this.id + '-hover');
        this.map.getSource(this.id) && this.map.removeSource(this.id);
        this.map.fire('removeLayer', {id: this.id});

    }

    /**
     * 创建线性控制style样式
     * @param {Array} arr  数据
     * @param {Number} min 最大值
     * @param {Number} max 最小值
     */
    buildSize(arr, min, max) {

        if (baseUtil.isArray(arr)) {

            return {
                property: 'value',
                stops: [
                    [min, arr[0]],
                    [max, arr[1]]
                ]
            };

        } else {

            return arr;

        }

    }
}

export default BaseLayer;