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,
width: 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%;
width: 100px;
height: auto;
z-index: 9;
background-color: #ffffff;
}
.contextmenu ul {
width: 100%;
padding: 6px 2px 0 2px;
list-style: none;
}
.contextmenu > ul > li {
width: 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,
width: 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>