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

概述

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

2、线数据绘制

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

/**
 * 在地图上展示线
 * @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();
}

绘制完后的效果如下:
image.png

3、面数据绘制

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

/**
 * 绘制多边形
 * @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'来实现。

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛老师讲GIS

感谢老板支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值