components/layer/routeLayer.js

/*``
 * @Author: tjc
 * @Date:   2017-04-20 17:03:05
 * @Last Modified by:   hydata
 * @Last Modified time: 2018-05-10 17:12:11
 * @Email: 304861063@qq.com
 * @File Path: F:\work\hyMap\src\components\layer\buildingLayer.js
 * @File Name: clustersLayer.js
 * @Descript:路径图层
 */
import baseUtil from '../../util/baseUtil';
import lineLayer from './lineLayer';
import symbolLayer from './symbolLayer';

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

/**
 * 路径层
 * 
 */
class RouteLayer {
    /**路径层
     * 初始化
     * @param {*} options 
     */
    constructor(options) {

        options.serie = {
            'symbolStyle': {
                'normal': {
                    'line-color':
                    {
                        'property': 'type',//属性字段 区分大小写
                        'type': 'categorical',
                        'default': '#00bd63',//如果该属性不存在
                        'stops': [
                                ['walk', '#00bd01'],//值=1
                                ['slow', 'yellow']
                        ]
                    },
                    'line-width': 6
                },
                'emphasis': {
                    'line-width': 8
                }
            }
        };
        this.url = 'http://192.168.11.50:8080/geoserver/hygis/wfs?sversion=1.0.0&request=GetFeature&outputFormat=application%2Fjson';
        this.setUrl(options.serverUrl);
        this.line = {
            'type': 'FeatureCollection',
            'features': [],
            '_LKey': this.LAYERKEY
        };
        this.minLength = 10e6;
        options.serie.data = this.line;
        this.map = options.map;
        this.init();

    }

    /**
     * 初始化
     */
    init() {

        this.outlineLayer = new lineLayer({
            serie: {
                'symbolStyle': {
                    'normal': {
                        'line-color': '#fff',
                        'line-width': 10
                    },
                    'emphasis': {
                        'line-width': 10
                    }
                }
            },
            map: this.map
        });
        this.lineLayer = new lineLayer({
            serie: {
                'symbolStyle': {
                    'normal': {
                        'line-color':
                        {
                            'property': 'type',//属性字段 区分大小写
                            'type': 'categorical',
                            'default': '#00bd63',//如果该属性不存在
                            'stops': [
                                    ['walk', '#00bd01'],//值=1
                                    ['slow', 'yellow']
                            ]
                        },
                        'line-width': 8
                    },
                    'emphasis': {
                        'line-width': 8
                    }
                }
            },
            map: this.map
        });
        this.symbolLayer = new symbolLayer({
            serie: {
                'symbolStyle': {
                    'normal': {
                        'icon-ignore-placement': true,
                        'symbol-placement': 'line',
                        'symbol-spacing': 60,
                        'icon-size': 1,
                        'icon-image': 'oneway-white-large'
                    },
                    'emphasis': {
                        'icon-size': 1
                    }
                }
            },
            map: this.map
        });

    }

    /**
     * 设置url
     * @param {*} url 
     */
    setUrl(url) {

        this.url = url;

    }

    /**
     * 更新
     */
    update() {

        this.outlineLayer.update({ data: this.line });
        this.lineLayer.update({ data: this.line });
        this.symbolLayer.update({ data: this.line });

    }

    /**
     * 绘制轨迹
     * @param  {Array}   start              [description]
     * @param  {Array}   end                [description]
     * @param  {Function}   callback   [description]
     * @param  {Function}   tooltipFun [description]
     * @param  {Boolean}    isCustom  [description]
     */
    drawTrack(start,
        end, {
            dataUrl,
            callback = undefined,
            isCustom = false,
            tbName = 'road_jining'
        } = {}) {

        if (!start || !end) {

            return;

        }
        //起始点一致,不进行查询
        if (start.toString() === end.toString()) {

            return;

        }

        const viewparams = [
            'tbname:' + '\'' + tbName + '\'',
            'x1:' + start[0],
            'y1:' + start[1],
            'x2:' + end[0],
            'y2:' + end[1]
        ];
        let url = this.url +
            '/hygis/wfs?sversion=1.0.0&request=GetFeature&outputFormat=application%2Fjson';
        url += '&typeName=' + 'Route' + '&viewparams=' + viewparams.join(';');
        if (dataUrl) {

            url = dataUrl; //tjc修改

        }
        // let formData = new FormData();
        // formData.append("start", start);
        // formData.append("end", new ol.format.WKT().writeGeometry(end.getGeometry()));

        // let data = JSON.stringify({
        // start: start,
        // end: new ol.format.WKT().writeGeometry(end.getGeometry().clone().transform('EPSG:3857', "EPSG:4326"))
        // });
        fetch(url, {
            // mode: "cors",
            // headers: {
            // "Content-Type": "application/x-www-form-urlencoded",
            // 'Content-Type': 'application/json'
            // },
            // method: 'POST',
            // body: data
        }).then(response => {

            return response.json();

        }).then(data => {

            let feature = data.features[0];
            //构造结果
            const walkLine = this.getWalk(feature, start, end);
            this.addData(walkLine);
            //回调
            const length = turf.length(walkLine[0]) + turf.length(walkLine[1]) + turf.length(walkLine[2]);
            const time = Math.ceil(length / 1000 * 60 / 60);
            this.minLength = length < this.minLength ? length : this.minLength;
            data.length = length;
            data.time = time;
            data.features = walkLine;

            if (baseUtil.isFunction(callback)) {

                callback(data);

            }

        }).catch((e) => {

            if (callback) {

                callback({
                    length: Math.random() * 100 + 1000, //0,
                    time: Math.random() * 100
                });

            }
            console.error(e);

        });

    }

    /**
     * 增加数据
     * @param {*} data 
     */
    addData(data) {


        this.line.features = this.line.features.concat(data);

        this.update({ data: this.line });

    }

    /**
     * 获取步行路径
     * @param {*} line 
     * @param {*} start 
     * @param {*} end 
     */
    getWalk(line, start, end) {

        let walkLine = this.getNearLine(line, start);
        let walkLine1 = this.getNearLine(line, end);
        walkLine1.walkLine = this.changeDirrection(walkLine1.walkLine, start);
        let line1 = turf.lineSlice(walkLine.nearPoint, walkLine1.nearPoint, line);
        line1 = this.changeDirrection(line1, start);
        return [line1, walkLine.walkLine, walkLine1.walkLine];

    }

    /**
     * 改变线方向
     * @param {*} line 
     * @param {*} start 
     */
    changeDirrection=(line, start)=> {

        let coords = line.geometry.coordinates;
        const from = turf.point(start);
        const sPoint = turf.point(coords[0]);
        const ePoint = turf.point(coords[coords.length - 1]);
        const dis1 = turf.distance(from, sPoint);
        const dis2 = turf.distance(from, ePoint);
        dis1 > dis2 && coords.reverse(); //反向的路径进行坐标翻转
        return line;

    };

    /**
     * 获取最近的线
     * @param {*} line 
     * @param {*} point 
     */
    getNearLine=(line, point)=> {

        let endPoint = turf.point(point);
        let nearPoint = turf.nearestPointOnLine(line, endPoint);
        let walkLine = turf.lineString([endPoint.geometry.coordinates, nearPoint.geometry.coordinates], {
            type: 'walk'
        });

        return { nearPoint, walkLine };

    };

    /**
     * 清空
     */
    clear() {

        this.line.features = [];
        this.minLength = 10e6;
        this.update();

    }
}

export default RouteLayer;