百度地图 获取当前位置 添加标记物等基础使用 JavaScript API
目标:实现一个能自动定位我当前位置的地图,并且地图上能显示我想要标记物,以及能搜索地图对应的位置。这地图只能在IE浏览器上有效果,其他浏览器不支持。
先上效果图:
接下来说说怎么实现:
1.首先先去百度地图开放平台注册个账号:百度开发平台
然后点击控制台
填写开发者资料并认证。
2.接着去创建AK,也就是授权码,这个很关键,必须要去申请创建,要不然项目中没法调用百度地图的API。
这里应用名称随便写,应用类型选择服务端,启用服务按我图中勾选为主。
设置白名单IP:设置0.0.0.0/0就行
点完提交就能获取到AK了,记得保存下来,后面会用到。
3.在对应页面中,引入百度api的js
<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=你的AK"></script>
4.写上你想承载这地图dom元素
<div id="r-result">地点搜索:<input type="text" id="suggestId" size="20" placeholder="请输入地点信息..." style="width:250px;margin-top: 10px;margin-left:10px;padding: 0 20px;line-height: 36px;" /></div>
<div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div>
<div id="l-map" style="width:700px; height:680px;margin-top: 10px;"></div>
5.实现获取当前位置的Js代码:这里如果获取成功,会执行locationSuccess的回调方法。如果获取失败了,会执行locationError回调方法。
function getNowLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(locationSuccess, locationError, {
// 指示浏览器获取高精度的位置,默认为false
enableHighAccuracy: true,
// 指定获取地理位置的超时时间,默认不限时,单位为毫秒
timeout: 5000,
// 最长有效期,在重复获取地理位置时,此参数指定多久再次获取位置。
maximumAge: 3000
});
}else{
alert("浏览器不支持Html5来获取地理位置信息");
}
}
locationSuccess回调方法实现:也就是获取当前位置的经度和纬度(H5浏览器自带的定位功能),然后根据经度和纬度获取当前的位置(调用百度api方法)
function locationSuccess(position) {
let lat = position.coords.latitude;
let lng = position.coords.longitude;
const pointBak = new BMap.Point(lng, lat);
const convertor = new BMap.Convertor();
convertor.translate([pointBak], 1, 5,function(resPoint) {
if(resPoint && resPoint.points && resPoint.points.length>0){
lng = resPoint.points[0].lng;
lat = resPoint.points[0].lat;
}
console.log("当前位置经度为:" + lng + "纬度为:" +lat);
const point = new BMap.Point(lng, lat);
const geo = new BMap.Geocoder();
geo.getLocation(point, (rs) => {
var addComp = rs.addressComponents;
console.log(addComp);
var result = addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber;
console.log("当前的位置为:" + result);
initMap(lng, lat, result);
});
});
}
locationError回调方法实现:
function locationError(error) {
switch(error.code) {
case error.TIMEOUT:
alert("连接超时,请重试");
break;
case error.POSITION_UNAVAILABLE:
alert('非常抱歉,我们暂时无法为您所在的星球提供位置服务');
break;
case error.PERMISSION_DENIED:
alert('您拒绝了使用位置共享服务,查询已取消');
break;
default:
alert('发生未知错误!');
break;
}
}
6.接下来使用前面获取到的经度和纬度初始化百度地图:
function initMap(lng, lat, address) {
var map = new BMap.Map("l-map");
map.centerAndZoom(new BMap.Point(lng, lat), 20); // 初始化地图,设置城市和地图级别。
map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
markInfectiveLocation(map);
markNowLocation(map, lng, lat, address);
searchKeyWordNote(map);
}
7.initMap方法中调用了markInfectiveLocation()标记疫情位置方法和markNowLocation标记当前位置的方法和searchKeyWordNote搜索方法。分别看代码:
var infectiveAddress = [];
function markInfectiveLocation(map) {
<c:forEach items="${mapsList}" var="maps" varStatus="vs">
var maps = {
lng: "${maps.lng}",
lat: "${maps.lat}",
createTime: "${maps.createTime}",
location: "${maps.location}",
count: "${maps.count}",
};
infectiveAddress.push(maps);
</c:forEach>
for(let i=0; i<infectiveAddress.length; i++) {
let marker = new BMap.Marker(new BMap.Point(parseFloat(infectiveAddress[i].lng), parseFloat(infectiveAddress[i].lat)), {});
map.addOverlay(marker);
var opts = {
width : 70, // 信息窗口宽度
height: 100, // 信息窗口高度
title : "疫情情况" , // 信息窗口标题
};
let infoWindow = new BMap.InfoWindow('<span style="color:red">疫情位置:'+ infectiveAddress[i].location +'<br/>确诊人数:' + infectiveAddress[i].count + '<br/>登记时间:'+ format(infectiveAddress[i].createTime) +'</span>', opts); // 创建信息窗口对象
marker.addEventListener("click", function(){
map.openInfoWindow(infoWindow, new BMap.Point(parseFloat(infectiveAddress[i].lng), parseFloat(infectiveAddress[i].lat))); //开启信息窗口
});
map.openInfoWindow(infoWindow, new BMap.Point(parseFloat(infectiveAddress[i].lng), parseFloat(infectiveAddress[i].lat))); //开启信息窗口
}
}
//时间格式显示
function add0(m){return m<10?'0'+m:m }
function format(shijianchuo){
//shijianchuo是整数,否则要parseInt转换
var time = new Date(shijianchuo);
time.setHours(time.getHours() - 14);
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.getDate();
var h = time.getHours();
var mm = time.getMinutes();
var s = time.getSeconds();
return y+'-'+add0(m)+'-'+add0(d)+' '+add0(h)+':'+add0(mm)+':'+add0(s);
}
function markNowLocation(map, lng, lat, address) {
var marker = new BMap.Marker(new BMap.Point(lng, lat), {});
map.addOverlay(marker);
var opts = {
width : 70, // 信息窗口宽度
height: 30, // 信息窗口高度
title : "当前位置" , // 信息窗口标题
};
var infoWindow = new BMap.InfoWindow('地址:' + address, opts); // 创建信息窗口对象
marker.addEventListener("click", function(){
map.openInfoWindow(infoWindow, new BMap.Point(lng, lat)); //开启信息窗口
});
map.openInfoWindow(infoWindow, new BMap.Point(lng, lat)); //开启信息窗口
}
var pp = null;
function searchKeyWordNote(map) {
var ac = new BMap.Autocomplete( //建立一个自动完成的对象
{"input" : "suggestId"
,"location" : map
});
ac.addEventListener("onhighlight", function(e) { //鼠标放在下拉列表上的事件
var str = "";
var _value = e.fromitem.value;
var value = "";
if (e.fromitem.index > -1) {
value = _value.province + _value.city + _value.district + _value.street + _value.business;
}
str = "FromItem<br />index = " + e.fromitem.index + "<br />value = " + value;
value = "";
if (e.toitem.index > -1) {
_value = e.toitem.value;
value = _value.province + _value.city + _value.district + _value.street + _value.business;
}
str += "<br />ToItem<br />index = " + e.toitem.index + "<br />value = " + value;
G("searchResultPanel").innerHTML = str;
});
var myValue;
ac.addEventListener("onconfirm", function(e) { //鼠标点击下拉列表后的事件
var _value = e.item.value;
myValue = _value.province + _value.city + _value.district + _value.street + _value.business;
G("searchResultPanel").innerHTML ="onconfirm<br />index = " + e.item.index + "<br />myValue = " + myValue;
if(pp != null){
deletePointMarker(map);
}
setPlace(map, myValue);
});
layer.close(id);
}
Tips:这里${mapsList}是我从后端获取的数据,然后遍历,你们可以根据自己需求实现。
坑点:遍历标记物时候,直接遍历会导致所有标记物都只显示最后一条数据的数据。因此先用var infectiveAddress = [];进行存储,再对这个存储的数组进行遍历可以解决这个问题。
完整项目链接:SSM社区疫情管理系统