准备工作:
- 高德开发者账号(必须经过认证)
- 高德web_service_key(web服务key)
参考文档:
猎鹰服务-服务端 https://lbs.amap.com/api/track/lieying-kaifa/api/service
js多边形绘制https://lbs.amap.com/demo/javascript-api-v2/example/overlay-editor/polygon-editor-avoidpolygon/
注意事项:
- 申请好对应的key之后,需要先创建对应的service,一个key之下最多有15个service
- 每个service之间的数据并不互通
- 正常开发测试不会触发高德流量预警
创建猎鹰服务service
public function createService() { $params = [ 'name' => input('name'), 'desc' => input('desc'),//创建不同的service时,请更换描述 'key' => input('key'),//webapi key ]; $url = 'https://tsapi.amap.com/v1/track/service/add'; $arr = [ 'name' => $params['name'], 'desc' => $params['desc'], 'key' => $params['key'], ]; $res = $this->send_post($url, $arr);//res中包含唯一值sid,请务必将sid保存 print_r($res);exit; }
公共方法
public function send_post($url, $post_data) { $postdata = http_build_query($post_data); $options = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-type:application/x-www-form-urlencoded', 'content' => $postdata, 'timeout' => 15 * 60 // 超时时间(单位:s) ) ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); return $result; }
创建围栏
//创建圆形围栏 public function createCircle($name, $desc,$key,$sid,$center,$radius) { $url = 'https://tsapi.amap.com/v1/track/geofence/add/circle'; $arr = [ 'name' => $name,//每一个围栏的名称不能相同 'desc' => $desc,//每一个围栏的描述不能相同 'key' => $key, 'sid' => $sid, 'center' => $center,//格式如x,y--经度在前纬度在后 'radius' => $radius,//单位:米,整数,最小1最大50000 ]; $res = $this->send_post($url, $arr);//gfid围栏的唯一标识,务必保存 print_r($res);exit; } //创建多边形围栏 public function createPolygon($name, $desc, $points,$key,$sid) { $url = 'https://tsapi.amap.com/v1/track/geofence/add/polygon'; $arr['key'] = $key; $arr['sid'] = $sid; $arr['name'] = $name; $arr['desc'] = $desc; $arr['points'] = $points;//经度1,纬度1;经度2,纬度2;|||注意:经纬度之间用英文逗号分割,不同的点之间用英文分号分割 //且这些点组成的最大面积必须小于100平方公里(是面积不是距离),若想大于100平方公里请找高德客服 //points点的顺序必须是顺时针或者是逆时针,例:矩形的情况下第二个点不可为第一个点的对角点 //points最少传三个最多传100 $res = $this->send_post($url, $arr);//gfid围栏的唯一标识,务必保存 print_r($res);exit; } //线行围栏:就是一条直线,允许在直线上左右偏差1-300米 //行政区围栏:根据行政区划编码进行区域划分
查询围栏
public function geofenceList($arr) { $url = 'https://tsapi.amap.com/v1/track/geofence/list?key=' . $arr['key'] . '&sid=' . $arr['sid'];//不传gfids分页返回所有的围栏传了就返回gfids包含的围栏 $res = file_get_contents($url); return json_decode($res, true); }
删除围栏
public function delGeoFence($gfids,$arr) { $url = 'https://tsapi.amap.com/v1/track/geofence/delete'; $arr['key'] = 'web服务key'; $arr['sid'] = '对应的sid'; $arr['gfids'] = $gfids;//可以传多个,以英文逗号分割,最大为100--如果需全部删除,传#all删除所有的 $res = $this->send_post($url, $arr);//删除A成功了就会返回A return json_decode($res, true); }
查询指定坐标和围栏的关系
public function locationStatus($location, $gfids) { //gfids如果传了就只判断传入的值,可以传多个,以英文逗号分割 //如果不传就判断与传入sid下所有围栏的关系 $arr['key'] = '4f61f40afc5f0af9e42fcb7290209d5a'; $arr['sid'] = '1008773'; $url = 'https://tsapi.amap.com/v1/track/geofence/status/location?key=' . $arr['key'] . '&sid=' . $arr['sid'] . '&location=' . $location . '&gfids=' . $gfids; $res = file_get_contents($url);//data-results-in 0=不在1=在 return json_decode($res, true); }
js部分(fastadmin为例,前端纯小白,仅供参考)
<script src="/assets/js/jquery.min.js"></script> <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script> <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=jsapi---key&plugin=AMap.Geocoder,AMap.MouseTool"></script> <script type="text/javascript"> window._AMapSecurityConfig = { securityJsCode: 'jsapikey对应的安全密钥,申请完jsapikey之后就能看到', } </script> <script type="text/javascript"> // 表单提交 $('#submit').click(() => { $.ajax({ url: '/admin.php/road/road/add', type: 'post', dataType: 'json', data: $('form').serialize(), success: res => { console.log(res.code) if (res.code == 1) { window.close(); Fast.api.close(); location.href = '/admin.php/road.road/index' window.parent.location.reload(); } } }) return false }) // var nodeData = {:json_encode($treeList); }; //一、初始化 "地图中心" var lon = "{$row.lon}" ? "{$row.lon}" : 116.397413; var lat = "{$row.lat}" ? "{$row.lat}" : 39.920912; //二、初始地图中心点 var map1 = new AMap.Map("container", { center: [lon, lat], resizeEnable: true, zoom: 10 }); //二、初始地图中心点 var map2 = new AMap.Map("container2", { center: [lon, lat], resizeEnable: true, zoom: 10 }); let mouseTool1 = new AMap.MouseTool(map1) mouseTool1.on('draw', event => { console.log(event.obj.getPath()) let a = event.obj.getPath() let b = '' a.forEach((item, index) => { if (b) { b = b + ';' + item.lng + ',' + item.lat } else { b = item.lng + ',' + item.lat } }) $('#map_lat_1').val(b) mouseTool1.close() }) // 绘制围栏 $('#map1').click( () => { mouseTool1.close(true) mouseTool1.polygon({ strokeColor: "#FF33FF", strokeOpacity: 1, strokeWeight: 6, strokeOpacity: 0.2, fillColor: '#1791fc', fillOpacity: 0.4, // 线样式还支持 'dashed' strokeStyle: "solid", // strokeStyle是dashed时有效 // strokeDasharray: [30,10], }) return false }) let mouseTool2 = new AMap.MouseTool(map2) mouseTool2.on('draw', event => { let a = event.obj.getPath() let b = '' a.forEach((item, index) => { if (b) { b = b + ';' + item.lng + ',' + item.lat } else { b = item.lng + ',' + item.lat } }) $('#map_lat_2').val(b) mouseTool2.close() }) // 绘制围栏 $('#map2').click( () => { mouseTool2.close(true) mouseTool2.polygon({ strokeColor: "#FF33FF", strokeOpacity: 1, strokeWeight: 6, strokeOpacity: 0.2, fillColor: '#1791fc', fillOpacity: 0.4, // 线样式还支持 'dashed' strokeStyle: "solid", // strokeStyle是dashed时有效 // strokeDasharray: [30,10], }) return false }) </script>
html部分,fastadmin为例,仅供参考
<form id="add-form" class="form-horizontal" role="form" method="POST" action=""> <div class="form-group"> <label class="control-label col-xs-12 col-sm-2">{:__('起点所在位置')}:</label> <button class="btn" id="map1">绘制围栏</button> <input type="text" id="map_lat_1" name="row[lng_lat_1]"> <div class="col-xs-12 col-sm-12" id="map_box"> <div id="container"></div> <div class="input-card hidden" id="map_box_1"> <div class="input-item"> <div class="input-item-prepend"><span class="input-item-text">经纬度</span></div> <input id='lnglat' data-rule="required" type="text" value=""> </div> <!--<div class="input-item"> <div class="input-item-prepend"><span class="input-item-text">地址</span></div> <input id='address' data-rule="required" type="text" readonly value=""> </div> <div> <input id="regeo" type="button" class="btn describe" value="经纬度 -> 地址"> </div>--> </div> </div> </div> <div class="form-group"> <label class="control-label col-xs-12 col-sm-2">{:__('终点所在位置')}:</label> <button class="btn" id="map2">绘制围栏</button> <input type="text" id="map_lat_2" name="row[lng_lat_2]"> <div class="col-xs-12 col-sm-12" id="map_box2"> <div id="container2"></div> <div class="input-card hidden" id="map_box_2"> <div class="input-item"> <div class="input-item-prepend"><span class="input-item-text">经纬度</span></div> <input id='lnglat2' data-rule="required" type="text" value=""> </div> <!--<div class="input-item"> <div class="input-item-prepend"><span class="input-item-text">地址</span></div> <input id='address' data-rule="required" type="text" readonly value="" name="row[address]"> </div> <div> <input id="regeo" type="button" class="btn describe" value="经纬度 -> 地址"> </div>--> </div> </div> </div> <div class="form-group layer-footer"> <label class="control-label col-xs-12 col-sm-2"></label> <div class="col-xs-12 col-sm-8"> <button type="button" id="submit" class="btn btn-success btn-embossed">{:__('OK')}</button> <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button> </div> </div> </form>
<link rel="stylesheet" href="/assets/css/amap.css"/> <style> #map_box #container { width: 100%; height: 580px; } .describe { width: 10rem; margin-left: 3.8rem; display: inline; } .amap-icon img { width: 25px; height: 34px; } .amap-marker-label { border: 0; background-color: transparent; } #map_box { position: relative !important; } #map_box_1 { position: absolute !important; width: 28rem; } #map_box2 #container2 { width: 100%; height: 580px; } #map_box2 .input-card { display: flex; flex-direction: column; min-width: 0px; overflow-wrap: break-word; background-color: rgb(255, 255, 255); background-clip: border-box; width: 22rem; border-width: 0px; border-radius: 0.4rem; box-shadow: rgb(114 124 245 / 50%) 0px 2px 6px 0px; /*position: fixed;*/ bottom: 1rem; right: 1rem; flex: 1 1 auto; padding: 0.75rem 1.25rem; position: absolute !important; </style>