效果图
一、pages.json文件中加入
{ "path" : "pages/map/mapd", "style" : { "navigationBarTitleText" : "地图", "app-plus": { "subNVues":[ { "id": "mapsubd1", // 唯一标识 "path": "pages/map/subnvued/mapsubd1", // 页面路径 /*"type": "popup", 这里不需要*/ "style": { "position": "fixed", "top": "100px", "right": "20px", "width": "52px", "height": "120px", "z-index": 10000, "mask": "rgba(0,0,0,0)",// 遮罩层透明 "background": "transparent", "style": { "popGesture": "none" // 组织侧滑返回, none,close } } }, { "id": "mapsubd2", // 唯一标识 "path": "pages/map/subnvued/mapsubd2", // 页面路径 /*"type": "popup", 这里不需要*/ "style": { "position": "fixed", "bottom": "30px", "right": "20px", "width": "38px", "height": "70px", "z-index": 9998, "mask": "rgba(0,0,0,0)",// 遮罩层透明 "background": "transparent", "style": { "popGesture": "none" // 组织侧滑返回, none,close } } } ] } } },pages.json
二、创建子窗体文件mapsubd1.nuve文件
<template> <div class="wrapper"> <div class="rightbox"> <div class="boxitem btd" @click.stop="changeTab(3)" v-if="tabIndex3Show"> <image class="itemimg" :src="tabIndex3 ? map3 : map3" mode=""></image> <text class="itemname" :class="tabIndex3 ? '' : ''">线始点</text> </div> <div class="boxitem" @click.stop="changeTab(6)"> <image class="itemimg" :src="tabIndex6 ? map6: map66" mode=""></image> <text class="itemname" :class="tabIndex6 ? '' : ''">显示点</text> </div> </div> </div> </template> <script> export default { data() { return { map3: '/static/map/map3.png', map6: '/static/map/map6.png', map66: '/static/map/map66.png', tabIndex3Show: true, //线始点-是否展示 tabIndex6Show: true,//显示点 tabIndex3: true, tabIndex6: true, } }, methods: { //子窗口切换 changeTab(index) { var _this = this; //触发监听时间-传参ID var post_obj={}; post_obj.tool_id=index; if(index==3){ post_obj.tabIndex3=_this.tabIndex3; }else if(index==6){ _this.tabIndex6=!_this.tabIndex6; post_obj.tabIndex6=_this.tabIndex6; } uni.$emit('mapdtool', post_obj); }, } } </script> <style> .btd{ border-bottom: 1rpx dashed #ccc;width: 100%; } .wrapper { align-items: center; flex-direction: column; justify-content: center; /* padding: 10rpx 15rpx; */ background-color: #fff; /* width: 52px; */ /* box-shadow: 10rpx 14rpx 18rpx 10rpx rgba(0, 0, 0, 0.7); */ box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(200, 200, 200, 0.5); border-radius: 14rpx; } .rightbox { align-items: center; justify-content: center; /* padding: 0 12rpx; */ background: #FFFFFF; /* box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(200, 200, 200, 0.5); border-radius: 14rpx; */ } .boxitem { display: flex; flex-direction: column; text-align: center; align-items: center; justify-content: center; padding-bottom: 4rpx; padding-left: 16rpx; padding-right: 16rpx; } .itemimg { width: 40rpx; height: 40rpx; margin: 10rpx 4rpx; } .itemname { font-size: 22rpx; font-weight: 400; color: #333333; line-height: 42rpx; } .active { color: #2765F1; } .closeicon { width: 40rpx; height: 40rpx; position: absolute; right: 16rpx; top: 12rpx; } </style>mapsubd1.nvue
三、创建子窗体文件mapsubd2.nuve文件
<template> <div class="wrapper"> <div class="rightbox"> <div class="boxitem btd" @click.stop="changeTab(7)"> <image class="itemimg" :src="map7" mode=""></image> </div> <div class="boxitem" @click.stop="changeTab(8)"> <image class="itemimg" :src="map8" mode=""></image> </div> </div> </div> </template> <script> export default { data() { return { map7: '/static/map/map7.png', map8: '/static/map/map8.png', } }, methods: { //子窗口切换 changeTab(index) { var _this = this; //触发监听时间-传参ID //uni.$emit('mapdtool', {'tool_id': index}); var post_obj={}; post_obj.tool_id=index; uni.$emit('mapdtool', post_obj); }, } } </script> <style> .btd{ border-bottom: 1rpx dashed #ccc;width: 100%; } .wrapper { align-items: center; flex-direction: column; justify-content: center; /* padding: 10rpx 15rpx; */ background-color: #fff; box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(200, 200, 200, 0.5); border-radius: 14rpx; } .rightbox { align-items: center; justify-content: center; /* padding: 0 12rpx; */ background: #FFFFFF; /* box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(200, 200, 200, 0.5); border-radius: 14rpx; */ } .boxitem { display: flex; flex-direction: column; text-align: center; align-items: center; justify-content: center; padding-bottom: 4rpx; padding-left: 16rpx; padding-right: 16rpx; } .itemimg { width: 40rpx; height: 40rpx; margin: 10rpx 4rpx; } .itemname { font-size: 22rpx; font-weight: 400; color: #333333; line-height: 42rpx; } .active { color: #2765F1; } .closeicon { width: 40rpx; height: 40rpx; position: absolute; right: 16rpx; top: 12rpx; } </style>mapsubd2.nvue
四、创建主窗体文件mapd.nuve文件,注意一定要是nvue文件
<template> <view> <map style="width: 750rpx;" :style="'height:'+windowHeight*2+'rpx;'" id="mapd" :latitude="data_info.latitude" :longitude="data_info.longitude" :scale="data_info.scale" :markers="covers" :polyline='polyline' > </map> <cover-view class="disbox"> <text style="color: blue;font-size: 28rpx;">总长度:{{data_info.dis}}</text> </cover-view> </view> </template> <script> export default { data() { return { windowHeight : uni.getSystemInfoSync().windowHeight+22,//屏幕高度 tid:0,//任务ID data_info:{ 'latitude':'', 'longitude':'', 'scale':18,//缩放级别(类型为Number,默认值为16,缩放级别取值范围为5-18) 'dis':0,//轨迹长度 }, data_detail:[],//根据ID获取的详情信息 covers: [],// 标记点 //指定一系列坐标点,从数组第一项连线至最后一项 polyline:[], } }, onl oad(options) { var _this= this; if(options.tid){ _this.tid=options.tid; //获取详情 _this.get_details(); }else{ uni.showToast({ title:'参数错误', icon:'none' }) //uni.navigateBack(); return false; } const mapsubd1= uni.getSubNVueById('mapsubd1'); // 通过 id 获取 nvue 子窗体 const mapsubd2= uni.getSubNVueById('mapsubd2'); // 通过 id 获取 nvue 子窗体 mapsubd1.show('slide-in-left', 250); // 打开 nvue 子窗体 mapsubd2.show('slide-in-left', 250); // 打开 nvue 子窗体 //监听子窗口操作 uni.$on('mapdtool',(res)=>{ //console.log(res); var tool_id=res.tool_id; if (tool_id == 3) { //线始点 //第一个点跳转中心点start var lat =_this.data_detail.firstdata.latitude; var lon =_this.data_detail.firstdata.longitude; _this.mapToLocation(lat,lon); //第一个点跳转中心点end }else if(tool_id == 6){ //显示点与不显示点 if(res.tabIndex6){ //标点数据start _this.covers=_this.data_detail.markers; //标点数据end }else{ _this.covers=[]; } }else if(tool_id == 7 || tool_id == 8){ //缩放级别 _this.getzoom(tool_id); }else { } }) }, onUnload() { // 移除子窗口监听事件 //因为事件监听是全局的,所以使用 uni.$on ,需要使用 uni.$off 移除全局的事件监听,避免重复监听。 uni.$off('mapdtool'); }, methods: { //任务详情 get_details(){ var _this=this; let post_obj={}; post_obj.tid=_this.tid; uni.$u.api.task_detail(post_obj).then(res => { console.log(res); if (res.code == 1) { var data_detail=res.data; _this.data_detail=data_detail; //第一个点跳转中心点start var lat =data_detail.firstdata.latitude; var lon =data_detail.firstdata.longitude; _this.mapToLocation(lat,lon); //第一个点跳转中心点end //标点数据start _this.covers=data_detail.markers; //标点数据end //标线数据start _this.polyline=data_detail.polyline; //标线数据end //轨迹长度start _this.data_info.dis=data_detail.dis; //轨迹长度end } }) }, //重置中心位置 mapToLocation(lat,lon){ this.data_info.latitude=lat; this.data_info.longitude=lon; let mapObjs = uni.createMapContext('mapd', this) mapObjs.moveToLocation({ latitude: lat, longitude: lon }, { complete: res => {} }) }, //缩放级别 getzoom(tool_id) { let _this=this; let scale=_this.data_info.scale; if(tool_id==7 && scale<=18){ //缩放+ _this.data_info.scale=scale+1; }else if(tool_id==8 && scale>=5){ //缩放- _this.data_info.scale=scale-1; } }, } } </script> <style> .disbox { width: 750rpx; display: flex; justify-content: center; align-items: center; padding: 24rpx 0rpx; position: fixed; bottom: 18rpx; } </style>mapd.nvue
附php后端部分代码
五、后端数据渲染接口
public function task_detail(){ $post=request()->only(['user_id'=>0,'tid'=>0]); if($post['tid']==0){ return returnData(0,'操作失败'); } $data=[];//返回的参数 $where=[]; $info = TaskM::where('tid',$post['tid'])->where($where)->find(); $info['dm3data']=Dm3dataM::where('dm3Task_tid',$info['tid'])->select(); //第一个点坐标,用于确定中心位置start $firstdata=[]; $firstdata['latitude']=''; $firstdata['longitude']=''; if($info['dm3data']){ $firstdata['latitude']=$info['dm3data'][0]['latitude']; $firstdata['longitude']=$info['dm3data'][0]['longitude']; } $info['firstdata']=$firstdata; //第一个点坐标,用于确定中心位置end //标点数据start $markers=[]; $polyline=[]; $points=[]; $polylinearr=[]; $dis=0;//轨迹长度 if($info['dm3data']){ //$d_l=count($info['dm3data']); foreach ($info['dm3data'] as $k=>$v){ if($k>=1){ // 起点坐标 $longitude1 =$info['dm3data'][$k-1]['longitude']; $latitude1 = $info['dm3data'][$k-1]['latitude']; // 终点坐标 $longitude2 = $info['dm3data'][$k]['longitude']; $latitude2 = $info['dm3data'][$k]['latitude']; $distance = getDistance($longitude1, $latitude1, $longitude2, $latitude2); $dis+=$distance; } $arr=[]; $arr['id']=$k+1; $arr['width']=22; $arr['height']=30; $arr['rotate']=0; $arr['latitude']=$v['latitude']; $arr['longitude']=$v['longitude']; $arr['iconPath']='/static/map/mark1.png'; //markers图标上数字start $label['content']=$k+1; $label['color']='#333333'; $label['display']='ALWAYS'; $label['y']=-26; $label['x']=-3; $label['bgColor']='transparent'; $arr['label']=$label; //markers图标上数字end array_push($markers,$arr); $arr1=[]; $arr1['latitude']=$v['latitude']; $arr1['longitude']=$v['longitude']; array_push($points,$arr1); } $polyline['points']=$points; $polyline['color']='#31c27c'; $polyline['width']=20; $polyline['arrowLine']=true; $polyline['borderWidth']=2; //$polyline['arrowIconPath']='/static/map/mapline.png'; } $info['dis']=$dis.'m';//轨迹长度 $info['markers']=$markers; $info['polyline']=[]; array_push($polylinearr,$polyline); $info['polyline']=$polylinearr; //标点数据end $data=$info; return returnData(1,'成功',$data); }数据渲染方法
六、计算两点距离方法
/** * 计算两点地理坐标之间的距离 * @param Decimal $longitude1 起点经度 * @param Decimal $latitude1 起点纬度 * @param Decimal $longitude2 终点经度 * @param Decimal $latitude2 终点纬度 * @param Int $unit 单位 1:米 2:公里 * @param Int $decimal 精度 保留小数位数 * @return Decimal */ function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit=1, $decimal=2){ $EARTH_RADIUS = 6370.996; // 地球半径系数 $PI = 3.1415926; $radLat1 = $latitude1 * $PI / 180.0; $radLat2 = $latitude2 * $PI / 180.0; $radLng1 = $longitude1 * $PI / 180.0; $radLng2 = $longitude2 * $PI /180.0; $a = $radLat1 - $radLat2; $b = $radLng1 - $radLng2; $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2))); $distance = $distance * $EARTH_RADIUS * 1000; if($unit==2){ $distance = $distance / 1000; } return round($distance, $decimal); }计算两点距离的方法
标签:info,map,轨迹,center,longitude,unipp,latitude,data,id From: https://www.cnblogs.com/zhangyouwu/p/18036500