unipp实现map地图轨迹,轨迹长度,标点,连线功能
效果图

一、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 } } } ] } } },
二、创建子窗体文件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>
三、创建子窗体文件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>
四、创建主窗体文件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:[],
}
},
onLoad(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>
附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); }

浙公网安备 33010602011771号