跟牛老师一起学WEBGIS——WEBGIS实现(绘制线和面)

2020-12-07 15:59:36 浏览数 (1)

概述

前面的文章绘制点中实现了点的绘制,本文说说线和面的绘制实现。

2、线数据绘制

在canvas中可以通过ctx.lineTo(x, y)ctx.stroke()实现线的绘制。绘制线的代码如下:

代码语言:javascript复制
/**
 * 在地图上展示线
 * @private
 */
VectorLayer.prototype._showLine2Map = function () {
    const that = this;
    const features = that._data.features;
    for (let i = 0; i < features.length; i  ) {
        const coordinates = features[i].geometry.coordinates;
        that._drawLine(coordinates);
    }
}
/**
 * 在地图上展示多线
 * @private
 */
VectorLayer.prototype._showMultiLine2Map = function () {
    const that = this;
    const features = that._data.features;
    const lineStyle = that._lineStyle;
    for (let i = 0; i < features.length; i  ) {
        const coordinates = features[i].geometry.coordinates;
        for (let j = 0; j < coordinates.length; j  ) {
            that._drawLine(coordinates[j]);
        }
    }
}
/**
 * 在地图上绘制线
 * @param coordinates
 * @private
 */
VectorLayer.prototype._drawLine = function (coordinates = []) {
    const that = this;
    const lineStyle = {
        width: 3,
        color: '#ff0000',
        opacity: 0.5,
        dash: [10, 6]
    };
    for (let i = 0; i < coordinates.length; i  ) {
        const coords = coordinates[i];
        const pixel = that._map2pixel(coords);
        const x = pixel.x, y = pixel.y;
        if(i === 0) {
            that._ctx.moveTo(x, y);
            that._ctx.beginPath();
        }
        that._ctx.lineTo(x, y);
    }
    that._ctx.strokeStyle = that._convertHexToRGB(lineStyle.color, lineStyle.opacity);
    that._ctx.lineWidth = lineStyle.width;
    that._ctx.setLineDash(lineStyle.dash || [0, 0]);
    that._ctx.stroke();
}

绘制完后的效果如下:

3、面数据绘制

在canvas中可以通过ctx.lineTo(x, y)ctx.closePath()ctx.stroke()实现面的绘制。绘制面的代码如下:

代码语言:javascript复制
/**
 * 绘制多边形
 * @private
 */
VectorLayer.prototype._showPolygon2Map = function () {
    const that = this;
    const features = that._data.features;
    const fillStyle = that._fillStyle;
    for (let i = 0; i < features.length; i  ) {
        const coordinates = features[i].geometry.coordinates;
        for (let j = 0; j < coordinates.length; j  ) {
            const _coordinates = coordinates[j];
            if(fillStyle.fillColor) {
                that._drawPolygon(_coordinates);
            }
            if(fillStyle.borderWidth) {
                that._drawPolygonBorder(_coordinates);
            }
        }
    }
}
/**
 * 绘制复杂多边形
 * @private
 */
VectorLayer.prototype._showMultiPolygon2Map = function () {
    const that = this;
    const features = that._data.features;
    const fillStyle = that._fillStyle;
    for (let i = 0; i < features.length; i  ) {
        const coordinates = features[i].geometry.coordinates;
        for (let j = 0; j < coordinates.length; j  ) {
            let _coordinates = coordinates[j].concat([]);
            for (let k = 0; k < _coordinates.length; k  ) {
                const __coordinates = _coordinates[k];
                if(fillStyle.fillColor) {
                    // 处理中空的情况
                    const _clip = _coordinates.length > 1 && k === _coordinates.length - 1;
                    that._ctx.globalCompositeOperation = _clip ? 'destination-out' :'source-over';
                    that._drawPolygon(__coordinates);
                }
                that._ctx.globalCompositeOperation = 'source-over';
                if(fillStyle.borderWidth) {
                    that._drawPolygonBorder(__coordinates);
                }
            }
        }
    }
}
/**
 * 绘制多边形
 * @param coordinates
 * @param fillColor
 * @private
 */
VectorLayer.prototype._drawPolygon = function (coordinates) {
    const that = this;
    for(let i = 0; i < coordinates.length; i  ) {
        const coords = coordinates[i];
        const pixel = that._map2pixel(coords);
        const x = pixel.x, y = pixel.y;
        if(i === 0) {
            that._ctx.moveTo(x, y);
            that._ctx.beginPath();
        }
        that._ctx.lineTo(x, y);
    }
    that._ctx.closePath();
    const fillStyle = that._fillStyle;
    that._ctx.fillStyle = that._convertHexToRGB(fillStyle.fillColor, fillStyle.fillOpacity);
    that._ctx.fill();
}
/**
 * 绘制多边形边框
 * @param coordinates
 * @param fillColor
 * @private
 */
VectorLayer.prototype._drawPolygonBorder = function (coordinates) {
    const that = this;
    for(let i = 0; i < coordinates.length; i  ) {
        const coords = coordinates[i];
        const pixel = that._map2pixel(coords);
        const x = pixel.x, y = pixel.y;
        if(i === 0) {
            that._ctx.moveTo(x, y);
            that._ctx.beginPath();
        }
        that._ctx.lineTo(x, y);
    }
    const fillStyle = {
        fillColor: '#00f',
        fillOpacity: 0.4,
        borderWidth: 2,
        borderColor: '#ff0000',
        borderOpacity: 0.8,
        borderDash: [10, 6]
    };
    that._ctx.strokeStyle = that._convertHexToRGB(fillStyle.borderColor, fillStyle.borderOpacity);
    that._ctx.lineWidth = fillStyle.borderWidth;
    that._ctx.setLineDash(fillStyle.borderDash || [0, 0]);
    that._ctx.stroke();
}

实现后效果如下:

**注意:**在绘制多边形的时候需要处理中空的情况,可以设置ctx.globalCompositeOperation = 'destination-out'来实现。

0 人点赞