leaflet 曲線

項目開發過程中有繪製歷史軌跡的功能,上面說直線繪製效果不是太好,想看看曲線繪製的效果。

由於leaflet沒有提供繪製曲線的方法,只能自己算出曲線的座標點以直線相連,繪製成曲線
算法部分https://blog.csdn.net/TarkuNi/article/details/99054036

<!DOCTYPE html>
<html>
<head>
    <meta charset=utf-8 />
    <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui' />
    <title>Leaflet Side-by-side</title>
    <script src="https://www.jq22.com/jquery/jquery-3.3.1.js"></script>
    <script src='http://cdn.leafletjs.com/leaflet/v1.3.1/leaflet.js'></script>
    <link href='http://cdn.leafletjs.com/leaflet/v1.3.1/leaflet.css' rel='stylesheet' />
    <style>
    body {
        margin: 0;
        padding: 0;
    }
    #map {
        position: absolute;
        top: 0px;
        bottom: 0;
        width: 100%;
    }
    </style>
</head>

<body>
    <!-- <input type="checkbox" name="async" checked id="" onclick="checkClick()">同步 -->
    <div id='map'></div>

    <script>
        var map = L.map('map').setView([51.505, -0.09], 13);

        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);

        L.marker([51.5, -0.09]).addTo(map)
            .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
            .openPopup();
        
        
        calcCoorArr=(point_start,point_end,num)=>{// 入參兩個座標(字符串格式:"114.30911,30.600052"),num是返回座標點個數
          //第一步把座標字符串轉爲對象,爲了方便計算轉爲了數字格式
            var p_start={x:parseFloat(point_start.split(",")[0]),y:parseFloat(point_start.split(",")[1])};
            var p_end={x:parseFloat(point_end.split(",")[0]),y:parseFloat(point_end.split(",")[1])};
            //此處敲黑板,是任務的第二大難點,求出相對的第三個點,用於固定曲線的彎曲度,下面公式是已知三角形兩點座標和兩個座標點的夾角求第三點座標,兩個夾角我們是自定義任意值,不過不要加起來超過180度
              // 已知兩點p1(x1,y1)、p2(x2,y2)和兩點所對應的角度A和B,x3、y3是對應第三點的座標,cot25°=2.14
            //x3 = (x1*cotB+x2*cotA+y2-y1)/(cotA+cotB)
            //y3 = (y1*cotB+y2*cotA+x1-x2)/(cotA+cotB)
            let x3=(p_start.x*2.14+p_end.x*2.14-p_start.y+p_end.y)/(2*2.14)
            let y3=(p_start.y*2.14+p_end.y*2.14-p_end.x+p_start.x)/(2*2.14)
            var p_crt1={x:x3,y:y3};
            var p_crt2={x:x3,y:y3};
              //下面計算貝葉斯曲線,不是幾個字能說清,直接拿去用沒毛病
            /**
             * 計算公式:
             *                  | 1  0  0   0|  |P0|
             * [1 t t*t  t*t*t] |-3  3  0   0|  |P1|
             *                  |3  -6  3   0|  |P2|
             *                  |-1  3  -3  1|  |p3|
             *
             * **/
            let paths=[];
            for(let i=0;i<num+1;i++){
                let t=i/num;
                var _matrix1=[1,t,t*t,t*t*t];
                var _matrix2=[
                [1,0,0,0]
                ,[-3,3,0,0]
                ,[3,-6,3,0]
                ,[-1,3,-3,1]
                ];
                var _matrix3=[
                [p_start.x,p_start.y]
                ,[p_crt1.x,p_crt1.y]
                ,[p_crt2.x,p_crt2.y]
                ,[p_end.x,p_end.y]
                ];
                var _matrix_tmp=[
                _matrix1[0]*_matrix2[0][0]+_matrix1[1]*_matrix2[1][0]+_matrix1[2]*_matrix2[2][0]+_matrix1[3]*_matrix2[3][0]
                ,_matrix1[0]*_matrix2[0][1]+_matrix1[1]*_matrix2[1][1]+_matrix1[2]*_matrix2[2][1]+_matrix1[3]*_matrix2[3][1]
                ,_matrix1[0]*_matrix2[0][2]+_matrix1[1]*_matrix2[1][2]+_matrix1[2]*_matrix2[2][2]+_matrix1[3]*_matrix2[3][2]
                ,_matrix1[0]*_matrix2[0][3]+_matrix1[1]*_matrix2[1][3]+_matrix1[2]*_matrix2[2][3]+_matrix1[3]*_matrix2[3][3]
                ];
                var _matrix_final=[
                _matrix_tmp[0]*_matrix3[0][0]+_matrix_tmp[1]*_matrix3[1][0]+_matrix_tmp[2]*_matrix3[2][0]+_matrix_tmp[3]*_matrix3[3][0]
                ,_matrix_tmp[0]*_matrix3[0][1]+_matrix_tmp[1]*_matrix3[1][1]+_matrix_tmp[2]*_matrix3[2][1]+_matrix_tmp[3]*_matrix3[3][1]
                ];
                //下面註釋掉的原因是入參是經緯度,但leaflet渲染需要的是緯度在前經度在後的數組,然後你懂的
                var _res_point=[
                  _matrix_final[0]
                  ,_matrix_final[1]
                ];
                // var _res_point=[_matrix_final[1],_matrix_final[0]];
                paths.push(_res_point);
            }
            return paths;
        }
        
        var path = calcCoorArr('51.5,-0.09','51.48,-0.041',20)
        console.log(path)
        L.polyline(path,{color:'blue'}).addTo(map).bindPopup("green to red");

        L.marker([51.48, -0.041]).addTo(map)

        var path2 = calcCoorArr('51.48,-0.041','51.48,-0.087',20)
        L.polyline(path2,{color:'blue'}).addTo(map).bindPopup("green to red");

        L.marker([51.48, -0.087]).addTo(map)
        
        var path3 = calcCoorArr('51.48,-0.087','51.49,-0.014',20)
        L.polyline(path3,{color:'blue'}).addTo(map).bindPopup("green to red");

        L.marker([51.49, -0.014]).addTo(map)

        map.on('click',function(e){
            // 用於調試 獲取點擊的座標和地圖級別
            console.log(e.latlng)
            console.log(map.getZoom())
        })
    </script>
</body>
</html>

貝葉斯曲線理論

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章