• OpenLayer4结合高德API实现地图选点路径规划


    前言:路径规划也是WebGIS一个特点,我们在做某些应用的时候可能会用到路径规划的功能,该功能我们也可以自己实现,利用数据等,但是OpenLayer一大特色就是加载在线地图,向高德,百度等,这些地图都提供一些api接口供大家调用获取数据,在做路径规划的时候,刚开始用的百度提供的api,发现这个路径规划的真烂你都不好意去吐槽,最后换成高德api总体效果还算满意。废话不多说进入正文。

    先来张图:

    一、高德地图加载

            var projection = ol.proj.get("EPSG:4326");
            function getNavmapLayer() {
                return new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: 'http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8'//7,8
                    }),
                    projection: projection
                });
            }
            var navlayer = getNavmapLayer();

    二、矢量图层的样式设置

            //矢量图层数据源
            sourceVector = new ol.source.Vector();
            //矢量图层
            var vector = new ol.layer.Vector({
                source: sourceVector,
                style: function (feature) {
                    var status = feature.get("status");
                    
                    
                    var _color = "#8f8f8f";
                    if (status === "拥堵") _color = "#e20000";
                    else if (status === "缓行") _color = "#ff7324";
                    else if (status === "畅通") _color = "#00b514";
    
                    return new ol.style.Style({
                        stroke: new ol.style.Stroke({
                            color: _color,
                             5,
                            lineDash:[10, 8]
                        }),
                    })
                }
            });

    只是简单地线行的渲染。

    三、地图点击事件

            //地图点击事件
            map.on("click", function (evt) {
                //获取坐标
                var coordate = evt.coordinate;
                console.log(evt.coordinate);
                console.log(coordate);
                //如果result为0,返回不做任何操作
                if (result == 0) {
                    return;
                }
                else {
                    if (result == 1) {
                        //起点
                        //构造提交api起点坐标
                        start = GetCoordate(coordate);
                        console.log("起点" + start);
                        name = "起点";
                        //矢量元素
                            var featureStart = new ol.Feature({
                                geometry: new ol.geom.Point(coordate),
                                name: '起点',//自定义属性
    
                            });
                            featureStart.setStyle(createFeatureStyle(featureStart,name));
                        sourceVector.addFeature(featureStart);
                    }
                    else {
                        //终点
                        //构造提交api终点坐标
                        name = "终点";
                        end = GetCoordate(coordate);
                        console.log("终点" + end);
                        //矢量元素
                        var featureEnd = new ol.Feature({
                            geometry: new ol.geom.Point(coordate),
                            name: '终点',//自定义属性
    
                        });
                        featureEnd.setStyle(createFeatureStyle(featureEnd,name));
                        sourceVector.addFeature(featureEnd);
                        ////请求数据
                        getRouteResult(start, end);
                    }
                }
            });

    该点击事件方法中涉及坐标的获取,赋值,以及ajax异步方式提交高德api获取数据。

    四、几个封装函数

    1、获取小数点后六位

      //保存小数点后六位
            function GetCoordate(coordate) {
                var lng = coordate[0].toString();
                var lat = coordate[1].toString();
                var lngIndex = lng.indexOf(".") + 7;
                var latIndex = lat.indexOf(".") + 7;
                lng = lng.substring(0, lngIndex);
                lat = lat.substring(0, latIndex);
                var str = lng + "," + lat;
                console.log(str.toString());
                return str;
            }

    2、获取数据

            //获取路径规划
            function getRouteResult(start, end) {
                var data = {
                    key: "",//申请的key值
                    origin: start,//起点
                    destination: end,//终点
                    extensions:"all"
                };
                $.ajax({
                    url: "https://restapi.amap.com/v3/direction/driving?",
                    type: "post",
                    dataType: "jsonp",
                    data: data,
                    success: function (result) {
                        console.log(result);
                        var routes = result["route"]["paths"][0];
                        console.log(routes);
                        //console.log(routes);
                        var steps = routes["steps"];
                        //console.log(steps);
                        for (var i = 0; i < steps.length; i++) {                       
                            var route = steps[i];
                            var path = route["tmcs"];
                            for (var k = 0; k < path.length; k++) {
                                var routePath = path[k];                           
                                var distance = routePath["distance"];
                                var polyline = routePath["polyline"].toString().split(";");
                                var status = routePath["status"];
                                var polylineData = [];
                                for (var j = 0; j < polyline.length; j++) {
                                    //将字符串拆成数组
                                    var realData = polyline[j].split(",");
                                    var coordinate = [realData[0], realData[1]];
                                    polylineData.push(coordinate);
                                    //要素属性
                                }
                                var attribute = {
                                    distance: distance,
                                };
                                //线此处注意一定要是坐标数组
                                var plygon = new ol.geom.LineString(polylineData);
                                //线要素类
                                var feature = new ol.Feature({
                                    geometry: plygon,
                                    attr: attribute,
                                    status: status
                                });
                                sourceVector.addFeature(feature);                         
                            }
                        }
                    }
                });
            };

    3、样式函数设置

            //样式函数
            var createFeatureStyle = function (feature, name) {
                var url;
                if (name==null) {
                    url = "../image/6起点.png";
                }
                else {
                    if (name=="起点") {
                        url = "../image/6起点.png";
                    }
                    else {
                        url = "../image/9终点.png";
                    }
                }
                return new ol.style.Style({
                    image: new ol.style.Icon(/** @type {olx.style.IconOptions} */({
                        anchor: [0.5, 60],
                        anchorOrigin: 'top-right',
                        anchorXUnits: 'fraction',
                        anchorYUnits: 'pixels',
                        offsetOrigin: 'top-right',
                        offset: [0, 10],//偏移量设置
                        scale: 0.2,  //图标缩放比例
                        opacity: 0.75,  //透明度
                        src: url, //图标的url
                        
                    })),
                });
    
            }

    五、全部代码

    <!DOCTYPE HTML>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>高德路径规划demo</title>
        <link rel="stylesheet" href="https://openlayers.org/en/v4.5.0/css/ol.css" type="text/css">
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" type="text/css">
        <style type="text/css">
            .contextmenu {
                position: absolute;
                top: 100%;
                 100px;
                height: auto;
                z-index: 9;
                background-color: #ffffff;
            }
    
                .contextmenu ul {
                     100%;
                    padding: 6px 2px 0 2px;
                    list-style: none;
                }
    
                .contextmenu > ul > li {
                     100%;
                    text-align: center;
                    padding: 5px 0;
                }
    
                    .contextmenu > ul > li:hover {
                        background-color: rgba(255, 0, 0, 0.5);
                    }
        </style>
    </head>
    <body style="margin:0 0 0 0; padding:0 0 0 0;">
    
        <div id="contextmenu_container" class="contextmenu">
            <ul>
                <li><a id="start" href="#">设置起点</a></li>
                <li><a id="end" href="#">设置终点</a></li>
                <li><a id="clear" href="#">清除路径</a></li>
            </ul>
        </div>
        <div id="map"></div>
        <script src="https://openlayers.org/en/v4.5.0/build/ol.js"></script>
        <script src="../../Scripts/jquery/jquery-3.1.1.min.js"></script>
        <script type="text/javascript">
            var result = 0;
            var start;
            var end;
            var name;
            var projection = ol.proj.get("EPSG:4326");
            function getNavmapLayer() {
                return new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: 'http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8'//7,8
                    }),
                    projection: projection
                });
            }
            var navlayer = getNavmapLayer();
            var map = new ol.Map({
                target: document.getElementById("map"),
                layers: [
                    navlayer
                ],
                view: new ol.View({
                    center: [116.46, 39.92],
                    projection: 'EPSG:4326',
                    zoom: 4
                })
            });
            var menu_overlay = new ol.Overlay({
                element: document.getElementById("contextmenu_container"),
                positioning: 'center-center'
            });
            menu_overlay.setMap(map);
            //矢量图层数据源
            sourceVector = new ol.source.Vector();
            //矢量图层
            var vector = new ol.layer.Vector({
                source: sourceVector,
                style: function (feature) {
                    var status = feature.get("status");
                    
                    
                    var _color = "#8f8f8f";
                    if (status === "拥堵") _color = "#e20000";
                    else if (status === "缓行") _color = "#ff7324";
                    else if (status === "畅通") _color = "#00b514";
    
                    return new ol.style.Style({
                        stroke: new ol.style.Stroke({
                            color: _color,
                             5,
                            lineDash:[10, 8]
                        }),
                    })
                }
            });
            map.addLayer(vector);
            //菜单栏点击事件
            $("#start").click(function () {
                result = 1;
            });
            $("#end").click(function () {
                result = 2;
            });
            $("#clear").click(function () {
                result = 0;
                start = "";
                end = "";
                name = "";
                sourceVector.clear();
            });
            //地图点击事件
            map.on("click", function (evt) {
                //获取坐标
                var coordate = evt.coordinate;
                console.log(evt.coordinate);
                console.log(coordate);
                //如果result为0,返回不做任何操作
                if (result == 0) {
                    return;
                }
                else {
                    if (result == 1) {
                        //起点
                        //构造提交api起点坐标
                        start = GetCoordate(coordate);
                        console.log("起点" + start);
                        name = "起点";
                        //矢量元素
                            var featureStart = new ol.Feature({
                                geometry: new ol.geom.Point(coordate),
                                name: '起点',//自定义属性
    
                            });
                            featureStart.setStyle(createFeatureStyle(featureStart,name));
                        sourceVector.addFeature(featureStart);
                    }
                    else {
                        //终点
                        //构造提交api终点坐标
                        name = "终点";
                        end = GetCoordate(coordate);
                        console.log("终点" + end);
                        //矢量元素
                        var featureEnd = new ol.Feature({
                            geometry: new ol.geom.Point(coordate),
                            name: '终点',//自定义属性
    
                        });
                        featureEnd.setStyle(createFeatureStyle(featureEnd,name));
                        sourceVector.addFeature(featureEnd);
                        ////请求数据
                        getRouteResult(start, end);
                    }
                }
            });
            //获取路径规划
            function getRouteResult(start, end) {
                var data = {
                    key: "",//申请的key值
                    origin: start,//起点
                    destination: end,//终点
                    extensions:"all"
                };
                $.ajax({
                    url: "https://restapi.amap.com/v3/direction/driving?",
                    type: "post",
                    dataType: "jsonp",
                    data: data,
                    success: function (result) {
                        console.log(result);
                        var routes = result["route"]["paths"][0];
                        console.log(routes);
                        //console.log(routes);
                        var steps = routes["steps"];
                        //console.log(steps);
                        for (var i = 0; i < steps.length; i++) {                       
                            var route = steps[i];
                            var path = route["tmcs"];
                            for (var k = 0; k < path.length; k++) {
                                var routePath = path[k];                           
                                var distance = routePath["distance"];
                                var polyline = routePath["polyline"].toString().split(";");
                                var status = routePath["status"];
                                var polylineData = [];
                                for (var j = 0; j < polyline.length; j++) {
                                    //将字符串拆成数组
                                    var realData = polyline[j].split(",");
                                    var coordinate = [realData[0], realData[1]];
                                    polylineData.push(coordinate);
                                    //要素属性
                                }
                                var attribute = {
                                    distance: distance,
                                };
                                //线此处注意一定要是坐标数组
                                var plygon = new ol.geom.LineString(polylineData);
                                //线要素类
                                var feature = new ol.Feature({
                                    geometry: plygon,
                                    attr: attribute,
                                    status: status
                                });
                                sourceVector.addFeature(feature);                         
                            }
                        }
                    }
                });
            };
            //保存小数点后六位
            function GetCoordate(coordate) {
                var lng = coordate[0].toString();
                var lat = coordate[1].toString();
                var lngIndex = lng.indexOf(".") + 7;
                var latIndex = lat.indexOf(".") + 7;
                lng = lng.substring(0, lngIndex);
                lat = lat.substring(0, latIndex);
                var str = lng + "," + lat;
                console.log(str.toString());
                return str;
            }
            //样式函数
            var createFeatureStyle = function (feature, name) {
                var url;
                if (name==null) {
                    url = "../image/6起点.png";
                }
                else {
                    if (name=="起点") {
                        url = "../image/6起点.png";
                    }
                    else {
                        url = "../image/9终点.png";
                    }
                }
                return new ol.style.Style({
                    image: new ol.style.Icon(/** @type {olx.style.IconOptions} */({
                        anchor: [0.5, 60],
                        anchorOrigin: 'top-right',
                        anchorXUnits: 'fraction',
                        anchorYUnits: 'pixels',
                        offsetOrigin: 'top-right',
                        offset: [0, 10],//偏移量设置
                        scale: 0.2,  //图标缩放比例
                        opacity: 0.75,  //透明度
                        src: url, //图标的url
                        
                    })),
                });
    
            }
            $(map.getViewport()).on("contextmenu", function (e) {
                e.preventDefault();
                var coordinate = map.getEventCoordinate(e);
                menu_overlay.setPosition(coordinate);
            });
            $(map.getViewport()).on("click", function (e) {
                e.preventDefault();
                menu_overlay.setPosition(undefined);
            });
        </script>
    </body>
    </html>
  • 相关阅读:
    【Codeforces Round #435 (Div. 2) A B C D】
    【Codeforces 851D Arpa and a list of numbers】
    预科班第三次考试试卷总结
    python判断结构总结
    《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 4 章 答案
    《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 2 章 答案
    《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 1 章 答案
    python函数总结
    python字符串、列表和文件对象总结
    python字符串格式化之format
  • 原文地址:https://www.cnblogs.com/tuboshu/p/10752313.html
Copyright © 2020-2023  润新知