本文详细讲解了如何使用 JQuery+HTML+JavaScript
实现移动端页面中的地图位置选取功能。本文逐步展示了如何构建基本的地图页面,如何通过点击地图获取经纬度和地理信息,以及如何实现模糊查询地址并在地图上标注。最后,提供了完整的代码示例,并总结了基于地图API进行地图位置选点的开发过程,帮助开发者快速上手并应用到实际项目中。
一、百度地图API介绍
百度地图API为开发者提供了强大的地理信息服务,可以轻松实现地图显示、位置选取、路线规划等功能。这里主要介绍2.0版本和3.0版本的功能示例,以及路书的介绍。
2.0 API
2.0版本的API功能相对较少,主要用于简单的地图展示和位置标注,以下是一个基本的示例:
var map = new BMap.Map("container");
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);
3.0 API
3.0版本增加了更多的功能和优化,提升了地图加载速度和交互体验,以下是一个展示地图和标注的示例:
var map = new BMap.Map("container");
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);
var marker = new BMap.Marker(point);
map.addOverlay(marker);
百度路书
路书是百度地图API提供的一种记录和展示路线的功能,可以用来展示旅游路线、出行规划等,以下是一个基本示例:
var driving = new BMap.DrivingRoute(map, {
renderOptions: { map: map, autoViewport: true }
});
driving.search("起点", "终点");
本文将采用百度地图3.0 API来实现地图位置选点的功能,包括地图展示、点击地图选点、地理信息转经纬度、位置的模糊查询等。
二、初始化地图页面
首先,创建一个基本的HTML页面,并引入百度地图API:
<!DOCTYPE html>
<html>
<head>
<title>点击地图获取地址和经纬度</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="https://api.map.baidu.com/getscript?v=3.0&ak=你的ak&s=1"></script>
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
.main-div {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
}
form {
background: #f8f8f8;
padding: 5px;
}
.input-group {
display: flex;
align-items: center;
margin-bottom: 5px;
}
label {
flex: 0 0 60px;
margin-right: 15px;
white-space: nowrap;
}
input[type="text"] {
flex: 1;
padding: 10px;
box-sizing: border-box;
}
#allmap {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
}
</style>
</head>
<body>
<div class="main-div">
<div id="allmap"></div>
</div>
</body>
<script>
var map = new BMap.Map("allmap");
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);
</script>
</html>
实现效果:
三、增加地理信息模态框
在页面上方添加一个表单,用于显示和输入经纬度和地理信息:
<form>
<div class="input-group">
<label for="lng">经度</label>
<input type="text" name="lng" id="lng" value="" readonly />
</div>
<div class="input-group">
<label for="lat">纬度</label>
<input type="text" name="lat" id="lat" value="" readonly />
</div>
<div class="input-group">
<label for="address">地址</label>
<input type="text" name="address" id="address" />
</div>
</form>
将这段表单代码加入到 main-div
里。
同时,我们需要将地图向下移动240px,给模态框留出空间,字体修改为40px,适应手机端页面。
修改及新增的CSS如下(没有修改的样式继续保留):
<style>
label {
flex: 0 0 60px;
margin-right: 15px;
white-space: nowrap;
font-size: 40px;
}
input[type="text"] {
flex: 1;
padding: 10px;
box-sizing: border-box;
font-size: 40px;
}
#allmap {
width: 100%;
height: 100%;
position: absolute;
top: 240px;
}
.tangram-suggestion table {
width: 100% !important;
font-size: 32px !important;
line-height: 50px !important;
cursor: default !important;
}
.tangram-suggestion table tr td{
line-height: 40px !important;
height: 60px !important;
}
</style>
实现效果如图:
目前我们的表单还只是一个静态的,下面我们来实现给表单的动态赋值。
四、实现地图点击事件
下面,我们为地图添加点击事件,获取点击位置的经纬度,并通过 Geocoder
获取地理信息,将获取的经纬度填充到上方表单。
JavaScript
里添加如下代码:
map.addEventListener("click", function(e) {
document.getElementById('lng').value = e.point.lng;
document.getElementById('lat').value = e.point.lat;
var geoc = new BMap.Geocoder();
geoc.getLocation(e.point, function(rs) {
var addComp = rs.addressComponents;
document.getElementById('address').value = addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber;
});
});
实现效果如图:
点击地图上位置时,会触发点击事件,自动为上方表单动态赋值经纬度。
接着,我们优化代码,打开页面时自动定位到我们的位置,并实现点击事件时经纬度、地址的填充。
JavaScript
内容全部替换为:
var map = new BMap.Map("allmap");
var geoc = new BMap.Geocoder(); //地址解析对象
var markersArray = [];
var geolocation = new BMap.Geolocation();
var point = new BMap.Point(116.331398, 39.897445);
map.centerAndZoom(point, 32); // 中心点
geolocation.getCurrentPosition(function (r) {
if (this.getStatus() == BMAP_STATUS_SUCCESS) {
var mk = new BMap.Marker(r.point);
map.addOverlay(mk);
map.panTo(r.point);
map.enableScrollWheelZoom(true);
}
else {
alert('failed' + this.getStatus());
}
}, { enableHighAccuracy: true })
map.addEventListener("click", showInfo);
//清除标识
function clearOverlays() {
if (markersArray) {
for (i in markersArray) {
map.removeOverlay(markersArray[i])
}
}
}
//地图上标注
function addMarker(point) {
var marker = new BMap.Marker(point);
markersArray.push(marker);
clearOverlays();
map.addOverlay(marker);
}
//点击地图事件处理
function showInfo(e) {
document.getElementById('lng').value = e.point.lng;
document.getElementById('lat').value = e.point.lat;
geoc.getLocation(e.point, function (rs) {
var addComp = rs.addressComponents;
var address = addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber;
document.getElementById('sever_add').value = address;
});
map.clearOverlays();
addMarker(e.point);
}
实现效果如下:
至此,地图选取位置获得经纬度和地址信息的功能已经完成。
下面,我们来实现输入模糊地址来反向定位地图中的坐标,并获得精确的位置经纬度。
五、输入模糊地址定位地图坐标
通过Autocomplete实现地址模糊查询,并在选定地址后在地图上标注位置。
首先,我们给地址输入框的输入进行校验,增加JavaScript代码:
function validate() {
var sever_add = document.getElementsByName('sever_add')[0].value;
if (isNull(sever_add)) {
alert('请选择地址');
return false;
}
return true;
}
//判断是否是空
function isNull(a) {
return (a == '' || typeof (a) == 'undefined' || a == null) ? true : false;
}
}
接着,增加输入后的下列框事件和下拉框点击事件:
var ac = new BMap.Autocomplete( //建立一个自动完成的对象
{
"input": "sever_add"
, "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;
});
var myValue;
ac.addEventListener("onconfirm", function (e) { //鼠标点击下拉列表后的事件
var _value = e.item.value;
myValue = _value.province + _value.city + _value.district + _value.street + _value.business;
setPlace();
});
function setPlace() {
map.clearOverlays(); //清除地图上所有覆盖物
function myFun() {
var pp = local.getResults().getPoi(0).point; //获取第一个智能搜索的结果
map.centerAndZoom(pp, 32);
map.addOverlay(new BMap.Marker(pp)); //添加标注
document.getElementById('lng').value = pp.lng;
document.getElementById('lat').value = pp.lat;
}
var local = new BMap.LocalSearch(map, { //智能搜索
onSearchComplete: myFun
});
local.search(myValue);
}
实现效果如下:
输入 “云龙湖”,会显示模糊查询到的地点。
选择地点,地图自动跳转到目标地点为中心的界面,显示目标点标注,并返回经纬度、详细地址给上方表单。
至此,输入模糊地址定位地图坐标的功能已经实现。
六、页面全部源码
下面是本文页面的全部代码,为了方便测试,已经把 JavaScript
和 CSS
与 Html
写在一个页面内。
完整的源码如下:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>点击地图获取地址和经纬度map,address,lng,lat</title>
<meta name="robots" content="noindex, nofollow">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript"
src="https://api.map.baidu.com/getscript?v=3.0&ak=你的ak&s=1"></script>
<style>
body,
html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
.main-div {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
}
form {
background: #f8f8f8;
padding: 5px;
}
.input-group {
display: flex;
align-items: center;
margin-bottom: 5px;
}
label {
flex: 0 0 60px;
margin-right: 15px;
white-space: nowrap;
font-size: 40px;
}
input[type="text"] {
flex: 1;
padding: 10px;
box-sizing: border-box;
font-size: 40px;
}
#allmap {
width: 100%;
height: 100%;
position: absolute;
top: 240px;
}
.tangram-suggestion table {
width: 100% !important;
font-size: 32px !important;
line-height: 50px !important;
cursor: default !important;
}
.tangram-suggestion table tr td{
line-height: 40px !important;
height: 60px !important;
}
</style>
</head>
<body>
<div class="main-div">
<form method="post" action="" name="theForm" enctype="multipart/form-data" onsubmit="return validate()">
<div class="input-group">
<label for="lng">经度</label>
<input type="text" name="lng" id="lng" value="" readonly/>
</div>
<div class="input-group">
<label for="lat">纬度</label>
<input type="text" name="lat" id="lat" value="" readonly/>
</div>
<div class="input-group">
<label for="sever_add">地址</label>
<input type="text" name="sever_add" id="sever_add" value="" />
</div>
</form>
<div id='allmap'></div>
</div>
</body>
<script type="text/javascript">
function validate() {
var sever_add = document.getElementsByName('sever_add')[0].value;
if (isNull(sever_add)) {
alert('请选择地址');
return false;
}
return true;
}
//判断是否是空
function isNull(a) {
return (a == '' || typeof (a) == 'undefined' || a == null) ? true : false;
}
var map = new BMap.Map("allmap");
var geoc = new BMap.Geocoder(); //地址解析对象
var markersArray = [];
var geolocation = new BMap.Geolocation();
var point = new BMap.Point(116.331398, 39.897445);
map.centerAndZoom(point, 32); // 中心点
geolocation.getCurrentPosition(function (r) {
if (this.getStatus() == BMAP_STATUS_SUCCESS) {
var mk = new BMap.Marker(r.point);
map.addOverlay(mk);
map.panTo(r.point);
map.enableScrollWheelZoom(true);
}
else {
alert('failed' + this.getStatus());
}
}, { enableHighAccuracy: true })
map.addEventListener("click", showInfo);
//清除标识
function clearOverlays() {
if (markersArray) {
for (i in markersArray) {
map.removeOverlay(markersArray[i])
}
}
}
//地图上标注
function addMarker(point) {
var marker = new BMap.Marker(point);
markersArray.push(marker);
clearOverlays();
map.addOverlay(marker);
}
//点击地图事件处理
function showInfo(e) {
document.getElementById('lng').value = e.point.lng;
document.getElementById('lat').value = e.point.lat;
geoc.getLocation(e.point, function (rs) {
var addComp = rs.addressComponents;
var address = addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber;
document.getElementById('sever_add').value = address;
});
map.clearOverlays();
addMarker(e.point);
}
var ac = new BMap.Autocomplete( //建立一个自动完成的对象
{
"input": "sever_add"
, "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;
});
var myValue;
ac.addEventListener("onconfirm", function (e) { //鼠标点击下拉列表后的事件
var _value = e.item.value;
myValue = _value.province + _value.city + _value.district + _value.street + _value.business;
setPlace();
});
function setPlace() {
map.clearOverlays(); //清除地图上所有覆盖物
function myFun() {
var pp = local.getResults().getPoi(0).point; //获取第一个智能搜索的结果
map.centerAndZoom(pp, 32);
map.addOverlay(new BMap.Marker(pp)); //添加标注
document.getElementById('lng').value = pp.lng;
document.getElementById('lat').value = pp.lat;
}
var local = new BMap.LocalSearch(map, { //智能搜索
onSearchComplete: myFun
});
local.search(myValue);
}
</script>
</html>
七、可视化地图上位置选取功能总结
通过百度地图API,我们可以方便地实现地图位置选点的功能,提升用户体验。在本文中,我们介绍了如何构建基本的地图页面,如何实现点击地图获取经纬度和地理信息,以及通过模糊查询来标注地图位置。希望这篇教程能够帮助你快速上手百度地图API,并应用到实际项目中。
当然,地图的API还有很多,下面整理了一份目前市面上常用地图API对比,希望对你有所帮助。
地图API | 提供商 | 主要功能 | 优点 | 缺点 |
---|---|---|---|---|
百度地图API | 百度 | 地图展示、位置选取、路线规划、地理编码、逆地理编码、POI搜索 | 覆盖中国范围广,中文支持好,提供详细的中国本地数据 | 国际覆盖范围有限 |
谷歌地图API | 地图展示、位置选取、路线规划、地理编码、逆地理编码、街景服务 | 国际覆盖范围广,数据更新及时,街景服务优秀 | 国内使用受限 | |
高德地图API | 阿里巴巴 | 地图展示、位置选取、路线规划、地理编码、逆地理编码、POI搜索 | 中国本地数据详细,支持多种出行方式 | 国际覆盖范围有限 |
腾讯地图API | 腾讯 | 地图展示、位置选取、路线规划、地理编码、逆地理编码、POI搜索 | 提供丰富的中国本地数据,接口简单易用 | 国际覆盖范围有限 |
OpenStreetMap API | OpenStreetMap | 地图展示、位置选取、路线规划、地理编码、逆地理编码 | 免费且开源,数据覆盖全球,社区支持强 | 数据精度和更新频率可能不及商业地图API |
这些API各有特点,开发者可以根据项目需求选择合适的地图API。百度地图、高德地图和腾讯地图在中国本地服务方面具有优势,而谷歌地图和OpenStreetMap在国际覆盖范围方面表现较好。