在后台需要给划定的区域设定边界。得使用地图库中的图形绘制,然后把边界的坐标(经纬度)获取后存到服务器。
第一步 显示地图
<div id="container"></div>
<div class="info">
<div class="input-item">
<div class="input-item-prepend">
<span class="input-item-text" style="width:8rem;">请输入关键字</span>
</div>
<input id='tipinput' type="text">
</div>
</div>
引入存放地图的容器和右上角的输入关联框
搜索界面样式
.info {
padding: .75rem 1.25rem;
margin-bottom: 1rem;
border-radius: .25rem;
position: fixed;
top: 6rem;
background-color: white;
width: auto;
min-width: 22rem;
border-width: 0;
right: 2.5rem;
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
}
.input-item:last-child {
margin-bottom: 0;
}
.input-item {
position: relative;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-align: center;
align-items: center;
width: 100%;
height: 3rem;
}
.input-item-prepend {
margin-right: -1px;
}
.input-item-text {
width: 6rem;
text-align: justify;
padding: 0.4rem 0.7rem;
display: inline-block;
text-justify: distribute-all-lines;
text-align-last: justify;
-moz-text-align-last: justify;
-webkit-text-align-last: justify;
-ms-flex-align: center;
align-items: center;
margin-bottom: 0;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #495057;
text-align: center;
white-space: nowrap;
background-color: #e9ecef;
border: 1px solid #ced4da;
border-radius: .25rem;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.input-item-text, input[type=text], input[type=date], select {
height: calc(2.2rem + 2px);
}
.input-item>select:not(:first-child), .input-item>input[type=text]:not(:first-child), .input-item>input[type=date]:not(:first-child) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.input-item>select, .input-item>input[type=text], .input-item>input[type=date] {
position: relative;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
width: 1%;
margin-bottom: 0;
}
input[type=text], input[type=date] {
background: #fff;
padding: .375rem .75rem;
}
select, input[type=text], input[type=date] {
display: inline-block;
width: 100%;
padding: .375rem 1.75rem .375rem .75rem;
line-height: 1.5;
color: #495057;
vertical-align: middle;
background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;
background-size: 8px 10px;
border: 1px solid #ced4da;
border-radius: .25rem;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none
}
第二步 加载JS后引入地图拓展组件
引入地图JS
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=高德开放平台申请的开发KEY"></script>
AMap.plugin(['AMap.ToolBar', 'AMap.Scale', "AMap.MouseTool", "AMap.Autocomplete", 'AMap.Geolocation', ], function() {
// 在图面添加工具条控件,工具条控件集成了缩放、平移、定位等功能按钮在内的组合控件
map.addControl(new AMap.ToolBar());
// 在图面添加比例尺控件,展示地图在当前层级和纬度下的比例尺
map.addControl(new AMap.Scale());
// 在图面添加定位控件,用来获取和展示用户主机所在的经纬度位置
map.addControl(new AMap.Geolocation());
// 实例化Autocomplete
var autoOptions = {
input: 'tipinput',
}
autoComplete = new AMap.Autocomplete(autoOptions);
autoComplete.on('select', function(data) {
map.setZoomAndCenter(15, [data.poi.location.lng, data.poi.location.lat]); //同时设置地图层级与中心点
showTargetPosition(data.poi.location.lng, data.poi.location.lat);
});
autoComplete.on('complete', function(status, result) {});
autoComplete.on('error', function(status, result) {});
autoComplete.on('choose', function(status, result) {});
mouseTool = new AMap.MouseTool(map);
//监听draw事件可获取画好的覆盖物
mouseTool.on('draw', function(e) {
console.log(e.obj.getPath()); //获取路径/范围
console.log(e.obj);
paths = e.obj.getPath();
overlays.push(e.obj);
//绘制完禁止重绘制
stopDraw();
})
if (type != '') {
//需要绘图
var nums = paths.length;
var all_x = 0;
var all_y = 0;
var sharp = null;
if (type == 'rectangle') {
var southWest = new AMap.LngLat(parseFloat(paths[1].lng), parseFloat(paths[1].lat));
var northEast = new AMap.LngLat(parseFloat(paths[3].lng), parseFloat(paths[3].lat))
var bounds = new AMap.Bounds(southWest, northEast)
sharp = new AMap.Rectangle({
bounds: bounds,
fillColor: '#00b0ff',
strokeColor: '#80d8ff',
strokeStyle: 'dashed',
strokeColor: 'red',
strokeWeight: 6,
strokeOpacity: 0.5,
fillOpacity: 0.5,
strokeDasharray: [30, 10]
});
} else if (type == 'polygon') {
var list = [];
for (var i = 0; i < nums; i++) {
var p = new AMap.LngLat(parseFloat(paths[i].lng), parseFloat(paths[i].lat));
list.push(p);
}
sharp = new AMap.Polygon({
path: list,
fillColor: '#00b0ff',
strokeColor: '#80d8ff',
strokeStyle: 'dashed',
strokeColor: 'red',
strokeWeight: 6,
strokeOpacity: 0.5,
fillOpacity: 0.5,
strokeDasharray: [30, 10]
});
} else if (type == 'circle') {
for (var i = 0; i < nums; i++) {
all_x += parseFloat(paths[i].lng);
all_y += parseFloat(paths[i].lat);
}
var x = all_x / nums;
var y = all_y / nums;
var meter = parseInt(getFlatternDistance(y, x, paths[0].lat, paths[0].lng));
var sharp = new AMap.Circle({
center: new AMap.LngLat(x, y), // 圆心位置
radius: meter, // 圆半径
fillColor: '#00b0ff',
strokeColor: '#80d8ff',
strokeStyle: 'dashed',
strokeColor: 'red',
strokeWeight: 6,
strokeOpacity: 0.5,
fillOpacity: 0.5,
strokeDasharray: [30, 10]
});
}
overlays.push(sharp);
map.add(sharp);
map.setFitView([sharp])
}
});
第三步 监听下拉菜单 设定具体绘制类型 (矩形 圆 多边形)
form.on('select(style)', function(data) {
if (data.value != "") {
draw(data.value);
} else {
//关闭,true 并清除覆盖物
stopDraw();
}
});
额外要求
1.单击地图获取坐标
2.双击地图指定地点居中
3.只能允许设定一个区域
map.on('dblclick', function(ev) {
//双击坐标点居中显示
showTargetPosition(ev.lnglat.getLng(), ev.lnglat.getLat())
var position = new AMap.LngLat(ev.lnglat.getLng(), ev.lnglat.getLat());
map.setCenter(position);
});
map.on('click', function(ev) {
// 触发事件的对象
var target = ev.target;
// 触发事件的地理坐标,AMap.LngLat 类型
var lnglat = ev.lnglat;
// 触发事件的像素坐标,AMap.Pixel 类型
var pixel = ev.pixel;
// 触发事件类型
var type = ev.type;
showTargetPosition(ev.lnglat.getLng(), ev.lnglat.getLat())
if (overlays.length > 0) {
stopDraw();
layer.msg('如需绘制新的区域请点击按钮清除已画区域');
}
});
相应的封装方法
function submit() {
layer.confirm('确定提交修改后的区域信息?', function(index) {
$.post("/admin/{$mod}/{$ac}.html?", {
'submit': '1',
'formhash': '{FORMHASH}',
'_id': '{$_GET['
id ']}',
'type': $('select[name=style]').val(),
'paths': JSON.stringify(paths)
}, function(res) {
layer.close(index);
if (res.status) {
layer.msg('修改区域信息成功', {
time: 1000,
icon: 1
});
parent.save_zone_callback();
} else {
layer.msg(res.msg);
}
})
});
}
function stopDraw() {
mouseTool.close(false)
}
//清除地图允许重新绘制
function clearMap() {
map.remove(overlays)
overlays = [];
draw($('select[name=style]').val());
}
function setCenter() {
var nums = paths.length;
var all_x = 0;
var all_y = 0;
for (var i = 0; i < nums; i++) {
all_x += parseFloat(paths[i].lng);
all_y += parseFloat(paths[i].lat);
}
if (nums > 0) {
var x = all_x / nums;
var y = all_y / nums;
var position = new AMap.LngLat(x, y);
map.setCenter(position);
}
console.log(paths);
}
function draw(type) {
if (overlays.length > 0) {
layer.msg('如需绘制新的区域请点击按钮清除已画区域');
return false;
}
switch (type) {
case 'marker':
{
mouseTool.marker({
//同Marker的Option设置
});
break;
}
case 'polyline':
{
mouseTool.polyline({
strokeColor: '#80d8ff'
//同Polyline的Option设置
});
break;
}
case 'polygon':
{
mouseTool.polygon({
fillColor: '#00b0ff',
strokeColor: '#80d8ff',
strokeStyle: 'dashed',
strokeColor: 'red',
strokeWeight: 6,
strokeOpacity: 0.5,
strokeDasharray: [30, 10]
//同Polygon的Option设置
});
break;
}
case 'rectangle':
{
mouseTool.rectangle({
fillColor: '#00b0ff',
strokeColor: '#80d8ff',
strokeStyle: 'dashed',
strokeColor: 'red',
strokeWeight: 6,
strokeOpacity: 0.5,
strokeDasharray: [30, 10]
//同Polygon的Option设置
});
break;
}
case 'circle':
{
mouseTool.circle({
fillColor: '#00b0ff',
strokeColor: '#80d8ff',
strokeStyle: 'dashed',
strokeColor: 'red',
strokeWeight: 6,
strokeOpacity: 0.5,
strokeDasharray: [30, 10]
//同Circle的Option设置
});
break;
}
}
}
function showTargetPosition(lng, lat) {
$('input[name=position]').val(lng + ',' + lat);
}
function getFlatternDistance(lat1, lng1, lat2, lng2) {
var EARTH_RADIUS = 6378137.0; //单位M
var f = getRad((lat1 + lat2) / 2);
var g = getRad((lat1 - lat2) / 2);
var l = getRad((lng1 - lng2) / 2);
var sg = Math.sin(g);
var sl = Math.sin(l);
var sf = Math.sin(f);
var s, c, w, r, d, h1, h2;
var a = EARTH_RADIUS;
var fl = 1 / 298.257;
sg = sg * sg;
sl = sl * sl;
sf = sf * sf;
s = sg * (1 - sl) + (1 - sf) * sl;
c = (1 - sg) * (1 - sl) + sf * sl;
w = Math.atan(Math.sqrt(s / c));
r = Math.sqrt(s * c) / w;
d = 2 * w * a;
h1 = (3 * r - 1) / 2 / c;
h2 = (3 * r + 1) / 2 / s;
return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
}
function getRad(d) {
var PI = Math.PI;
return d * PI / 180.0;
}