• 0
  • 0

高德地图绘制矢量图形

2019-11-27 1063 0 admin 所属分类:开发组件

在后台需要给划定的区域设定边界。得使用地图库中的图形绘制,然后把边界的坐标(经纬度)获取后存到服务器。


第一步 显示地图

<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;
}


返回顶部