以openlayers为例,鼠标交互绘制贝塞尔光滑曲线

已被阅读 2718 次 | 文章分类:Openlayers | 2019-11-01 22:37

openlayers等gis插件提供的交互工具可以绘制折线段,但不能绘制光滑曲线,这里使用贝塞尔公式达到交互绘制光滑曲线目的;使用其他地图一样原理

一:贝赛尔曲线

贝塞尔曲线(Bezier curve)是计算机图形学中的概念,使用一个方程来描述一条曲线,根据方程的最高阶数,又分为线性贝赛尔曲线,二次贝塞尔曲线、三次贝塞尔曲线和更高阶的贝塞尔曲线;本教程可重置阶数来绘制不同阶数的贝赛尔曲线,贝赛尔曲线公式可自行百度,重点理解贝恩斯坦多项式,贝塞尔曲线公式js代码如下:

                                        
 // num! 阶乘
        function factorial(num) {
            if (num <= 1) {
                return 1;
            } else {
                return num * factorial(num - 1);
            }
        }
        /* n表示绘制贝塞尔曲线的阶数
         * {array} 控制点坐标集合 */
        function createBezierCurvePoints(n, arrPoints) {
            var Ptx = 0;
            var Pty = 0;
            var LineString = [];
            for (var t = 0; t < 1; t = t + 0.01) {
                Ptx = 0;
                Pty = 0;
                for (var i = 0; i <= n; i++) {
                    Ptx += (factorial(n) / (factorial(i) * factorial(n - i))) * Math.pow(1 - t, n - i) * Math.pow(t,
                        i) * arrPoints[i][0];
                    Pty += (factorial(n) / (factorial(i) * factorial(n - i))) * Math.pow(1 - t, n - i) * Math.pow(t,
                        i) * arrPoints[i][1];
                }
                LineString.push([Ptx, Pty]);
            }
            return LineString;
        }

                                        
                                    

二:完整代码

上完整的代码

                                        
<!DOCTYPE html>
<html>

<head>
    <title>geojson</title>
    <link rel="stylesheet" href="./data/ol.css" type="text/css" />
    <script src="./data/ol-debug.js"></script>
</head>
<body>
    <label>贝塞尔曲线</label>
    <input id='NBesizer' type='text' value=''>
    <input id='submit' type='button' value='确定'>
    <div id="map" class="map"></div>
    <script>
        var map = new ol.Map({
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                })
            ],
            target: "map",
            view: new ol.View({
                center: [0, 0],
                zoom: 2,
                projection: "EPSG:4326"
            })
        });
        var source = new ol.source.Vector({
            features: []
        });
        var layer = new ol.layer.Vector({
            source: source // layer-source  1:1
        });
        map.addLayer(layer)
        var Njie;
        var clickResult = [];
        document.getElementById('submit').onclick = function () {
            source.clear();
            Njie = document.getElementById('NBesizer').value;
            map.on('click', pointeClickHandler);
        }
        // num! 阶乘
        function factorial(num) {
            if (num <= 1) {
                return 1;
            } else {
                return num * factorial(num - 1);
            }
        }
        /* n表示绘制贝塞尔曲线的阶数
         * {array} 控制点坐标集合 */
        function createBezierCurvePoints(n, arrPoints) {
            var Ptx = 0;
            var Pty = 0;
            var LineString = [];
            for (var t = 0; t < 1; t = t + 0.01) {
                Ptx = 0;
                Pty = 0;
                for (var i = 0; i <= n; i++) {
                    Ptx += (factorial(n) / (factorial(i) * factorial(n - i))) * Math.pow(1 - t, n - i) * Math.pow(t,
                        i) * arrPoints[i][0];
                    Pty += (factorial(n) / (factorial(i) * factorial(n - i))) * Math.pow(1 - t, n - i) * Math.pow(t,
                        i) * arrPoints[i][1];
                }
                LineString.push([Ptx, Pty]);
            }
            return LineString;
        }

        function pointeClickHandler(evt) {
            clickResult.push(evt.coordinate);

            if (clickResult.length > parseInt(Njie)) {
                map.un('click', pointeClickHandler);
                clickResult = [];
            }
            if (clickResult.length >= 2) {
                var result = createBezierCurvePoints(clickResult.length - 1, clickResult);
                source.clear();
                createLine(result);
            }
        }

        function createLine(result) {
            var feature = new ol.Feature({
                geometry: new ol.geom.LineString(result)
            });
            var style = new ol.style.Style({
                stroke: new ol.style.Stroke({ //边界样式
                    color: 'blue',
                    width: 3,
                    // lineDash: [1, 2, 3, 4, 5, 6],
                })
            })
            feature.setStyle(style);
            source.addFeature(feature);
        }
    </script>
</body>

</html>
                                        
                                    

效果如下

小白GIS

QQ:3410192267 | 技术支持 微信:popstarqqsmall

Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号