OpenLayer——绘制带箭头的线

绘制带箭头的线,计算相对复杂,多少是有点影响性能了。更简单的做法:初始、目标点用不同的点进行强调即可。

 

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <link href="ol/ol.css" rel="stylesheet" type="text/css"/>
    <script type="text/javascript" src="ol/ol.js" charset="utf-8"></script>
</head>
<body>
<div id="map" style="width: 100%;height: 100%"></div>
<script>
    var layerVector = new ol.layer.Vector({
        source: new ol.source.Vector()
    });

    var map = new ol.Map({
        layers: [
            new ol.layer.Tile({
                source: new ol.source.OSM(),
            })
            , layerVector
        ],
        target: 'map',
        view: new ol.View({
            center: [12950000, 4860000],
            zoom: 7
        })
    });

    /**
     *  采用闭包的写法,封装一个style
     * @param resolution 比例尺(跟比例尺相关的一个量,暂不明确具体是什么)
     * @returns {[*]}
     */
    var featureStyles = function (resolution) {
        let feature = this;
        let geometry = feature.getGeometry();

        let styles = [
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: 'green',
                    width: 8
                })
            })
        ];

        /**
         * 根据两个点的坐标,找出中间值,在中间绘制箭头图标,并且根据两个点,确定图标的角度
         *
         * @param start 开始的点
         * @param end 结束的点
         */
        function draw(start, end) {
            let arrowLonLat = [(parseFloat(end[0]) + parseFloat(start[0])) / 2, (parseFloat(end[1]) + parseFloat(start[1])) / 2];
            let dx = parseFloat(end[0]) - parseFloat(start[0]);
            let dy = parseFloat(end[1]) - parseFloat(start[1]);
            //旋转角度计算
            let rotation = Math.atan2(dy, dx);
            feature.set("inRotation", rotation);
            //设置图标
            styles.push(new ol.style.Style({
                geometry: new ol.geom.Point(arrowLonLat),
                image: new ol.style.Icon({
                    src: 'img/routearrow.png',
                    anchor: [0.75, 0.5],
                    size: [8, 8],
                    rotateWithView: true,
                    rotation: -rotation
                })
            }));
        }


        /**
         * 取a/b两个点的n等分点
         * @param n 分母
         * @param m 分子
         * @param p1 a点
         * @param p2 b点
         * @returns {*[]}
         */
        function dividedPoint(n, m, p1, p2) {
            return [(p2[0] - p1[0]) / n * m + p1[0], (p2[1] - p1[1]) / n * m + p1[1]]
        }

        /**
         * 遍历所有的点
         */
        geometry.forEachSegment(function (start, end) {
            //求两点之间的距离,勾股定理的应用
            let res = Math.sqrt(Math.pow(Math.abs(end[1] - start[1]), 2) + Math.pow(Math.abs(end[0] - start[0]), 2));
            if (res !== 0) {
                //根据比例尺,算出两点之间需要绘制的箭头数量,下面的50是通过测试,获得的用户体验较好的一个值
                let n = Math.ceil(res / 50 / resolution);
                let pre = start;
                //从第一个点开始绘制,直到绘制完所有的箭头
                let m = 1;
                while (m <= n) {
                    let next = dividedPoint(n, m, start, end);
                    draw(pre, next);
                    pre = next;
                    m++;
                }
            }
        });
        return styles;
    };

    //一条线段
    var pointFeature2 = new ol.Feature({
        geometry: new ol.geom.LineString([[0, 0], [12950000, 4760000], [12850000, 4760000]])
    });

    //设置样式
    pointFeature2.setStyle(featureStyles);

    layerVector.getSource().addFeature(pointFeature2);
</script>
</body>
</html>

 

posted on 2022-11-30 08:40  疯狂的妞妞  阅读(1179)  评论(0编辑  收藏  举报

导航