效果图:
考勤打卡三步走:
- 在地图上绘制打卡区域:
例图:
附上代码:
<template>
<view class="page-map">
<map :polygons="polygons" :markers="markers" style="width: 100%; height: 50vh;" @tap="onTap"
:longitude="curLongitude" :latitude="curLatitude" id="myMap" />
<button v-if="!isDrawing" @click="startDrawing">开始绘制</button>
<button v-else @click="stopDrawing">结束绘制</button>
<button v-if="!isDrawing || points.length < 3" disabled>生成面</button>
<button v-else @click="createPolygon">生成面</button>
<button v-if="points.length < 3" disabled>重新绘制</button>
<button v-else @click="redrawPolygon">重新绘制</button>
<button v-if="points.length < 3 || polygons[0].points.length < 3" disabled>提交绘制</button>
<button v-else @click="sumbitPolygon">提交绘制</button>
</view>
</template>
<script>
export default {
data() {
return {
curLongitude: 113.324520,
curLatitude: 23.099994,
markers: [],
isDrawing: false,
points: [],
polygons: [{
points: [],
strokeWidth: 2,
strokeColor: '#ff9d9fdd',
fillColor: '#fd0000dd'
}],
mapContext: null,
selectedLocation: null
}
},
onReady() {
this.mapContext = uni.createMapContext('myMap')
},
methods: {
// 当用户点击地图时触发的事件 onTap
onTap(e) {
// 判断是否开始绘制
if (this.isDrawing) {
console.log(e)
// 获取点击地方的经纬度,并且设置一个小图标
const {
longitude,
latitude
} = e.detail
const point = {
longitude,
latitude
}
this.points.push(point)
const marker = {
id: this.markers.length + 1,
longitude,
latitude,
iconPath: '../../static/logo.png',
width: 20,
height: 20
}
this.markers.push(marker)
}
},
// 提交绘制
sumbitPolygon() {
uni.showToast({
title: '绘制成功',
icon: 'success',
duration: 1000
});
// 将所有点都转移到一个一维数组中
let arr = []
this.polygons[0].points.forEach(item => {
for (const key in item) {
arr.push(item[key])
}
});
// 每两个元素合并成一个新数组
const arr2 = arr.map((item, index) => {
if (index % 2 === 0) {
return [item, arr[index + 1]]
}
}).filter(item => item !== undefined)
// 转为经:纬,经:纬 格式的字符串
const str = arr2.map(item => item.join(':')).join(',')
console.log(str)
},
// 重新绘制
redrawPolygon() {
this.markers = []
this.polygons[0].points = []
this.points = []
},
// 开始绘制
startDrawing() {
this.isDrawing = true
},
// 结束绘制
stopDrawing() {
this.isDrawing = false
},
// 生成面
createPolygon() {
// 将 points 的数组中每个元素的经纬度信息转换为一个新的对象数组
const points = this.points.map(({
longitude,
latitude
}) => ({
longitude,
latitude
}))
if (points.length >= 3) {
const firstPoint = points[0]
points[points.length] = firstPoint
this.polygons[0].points = points
} else {
uni.showToast({
icon: 'none',
title: '至少需要 3 个点才能生成面'
})
}
}
}
}
</script>
<style lang="scss" scoped>
.currentPosition {
position: absolute;
right: 5%;
top: 42%;
z-index: 9;
border-radius: 50%;
background-color: white;
width: 90rpx;
height: 91rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style>
- 获取到用户定位,并跳转到当前用户定位:
uniapp开发小程序如何使用地图让用户选择位置,并跳转到相关位置?
getUserLocation() {
uni.getLocation({
type: 'gcj02',
success: res => {
console.log(res.latitude, res.longitude)
uni.showToast({
title: '已经来到当前手机定位',
duration: 800
});
},
fail: err => {
console.error(err);
}
});
},
执行上述方法小程序会自动跳转到地图搜索页,搜索选择地址后,点击确定然后返回所选地址的经纬度,那如何跳转到所选位置呢?我们进一步完善
<map style="width: 100%; height: 50vh;"
:longitude="curLongitude" :latitude="curLatitude" id="myMap" />
data() {
return {
curLongitude: 113.324520,
curLatitude: 23.099994,
mapContext: null,
}
},
onReady() {
this.mapContext = uni.createMapContext('myMap')
console.log(this.mapContext)
}
getUserLocation() {
uni.getLocation({
type: 'gcj02',
success: res => {
console.log(res.latitude, res.longitude)
this.curLongitude = res.longitude
this.curLatitude = res.latitude
//this.mapContext.moveToLocation():调用地图上下文中提供的移动到当前地图中心点位置的方法,让地图自动定位到新的中心点位置
this.mapContext.moveToLocation()
uni.showToast({
title: '已经来到当前手机定位',
duration: 800
});
},
fail: err => {
console.error(err);
}
});
},
uniapp开发小程序如何获取用户位置,并跳转到当前位置?
<map style="width: 100%; height: 50vh;" :longitude="curLongitude" :latitude="curLatitude" id="myMap" />
data() {
return {
curLongitude: 113.324520,
curLatitude: 23.099994,
mapContext: null,
selectedLocation: null
}
},
onReady() {
this.mapContext = uni.createMapContext('myMap')
console.log(this.mapContext)
},
searchLocation() {
//uni.chooseLocation():调用微信内置地图打开位置选择器,允许用户选择位置。
uni.chooseLocation({
success: res => {
this.selectedLocation = {
longitude: res.longitude,
latitude: res.latitude,
name: res.name,
address: res.address,
}
console.log(this.selectedLocation)
this.curLongitude = this.selectedLocation.longitude
this.curLatitude = this.selectedLocation.latitude
//this.mapContext.moveToLocation():调用地图上下文中提供的移动到当前地图中心点位置的方法,让地图自动定位到新的中心点位置
this.mapContext.moveToLocation()
uni.showToast({
title: '已经来到' + this.selectedLocation.name,
duration: 800
});
},
fail: err => {
console.log("已取消")
}
})
}
报错
如何遇到报错:getLocation:fail fail:require permission desc
这个错误主要是因为小程序在获取地理位置时没有进行权限授权,或者用户拒绝了该权限导致的
在manifest.json中配置如下:
"permission": {
"scope.userLocation": {
"desc": "获取地理位置用于小程序定位"
}
},
"requiredPrivateInfos": ["chooseLocation", "getFuzzyLocation"]
完成代码分享
两个功能的完整代码附上:
<template>
<view class="page-map">
<map style="width: 100%; height: 50vh;" :longitude="curLongitude" :latitude="curLatitude" id="myMap" />
<view class="currentPosition" @click="getUserLocation">
<uni-icons type="location-filled" size="30"></uni-icons>
定位
</view>
<view style="top:34%" class="currentPosition" @click="searchLocation">
<uni-icons type="search" size="30"></uni-icons>
搜索
</view>
</view>
</template>
<script>
export default {
data() {
return {
curLongitude: 113.324520,
curLatitude: 23.099994,
mapContext: null,
selectedLocation: null
}
},
onReady() {
this.mapContext = uni.createMapContext('myMap')
console.log(this.mapContext)
},
methods: {
searchLocation() {
uni.chooseLocation({
success: res => {
this.selectedLocation = {
longitude: res.longitude,
latitude: res.latitude,
name: res.name,
address: res.address,
}
console.log(this.selectedLocation)
this.curLongitude = this.selectedLocation.longitude
this.curLatitude = this.selectedLocation.latitude
this.mapContext.moveToLocation()
uni.showToast({
title: '已经来到' + this.selectedLocation.name,
duration: 800
});
},
fail: err => {
console.log("已取消")
}
})
},
getUserLocation() {
uni.getLocation({
type: 'gcj02',
success: res => {
console.log(res.latitude, res.longitude)
this.curLongitude = res.longitude
this.curLatitude = res.latitude
this.mapContext.moveToLocation()
uni.showToast({
title: '已经来到当前手机定位',
duration: 800
});
},
fail: err => {
console.error(err);
}
});
},
}
}
</script>
<style lang="scss" scoped>
.currentPosition {
position: absolute;
right: 5%;
top: 42%;
z-index: 9;
border-radius: 50%;
background-color: white;
width: 90rpx;
height: 91rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style>
- 判断用户经纬度是否在绘制图形经纬度范围内:
借助第三方库:turf/helpers
turf/helpers
是Turf.js库中的一个模块,用于提供一些辅助函数和工具,以简化地理空间分析和操作。Turf.js是一个流行的JavaScript地理空间分析库,它提供了许多功能强大且易于使用的函数,用于处理地理数据。
首先终端npm安装:turf/helpers,然后引入使用
<script>
import {
point,
polygon
} from '@turf/helpers';
const pointCoordinates = [114.1275xxxx, 22.6070xxx];
const polygonCoordinates = [
[114.1251xxx, 22.607911xx1625156],
[114.1242869xxx5, 22.607174xx4267],
[114.12552648903466, 22.6057xxx6267],
[114.1273xx44345, 22.60700xxx4],
[114.1251063xx85, 22.6079115xx5156]
];
const pt = point(pointCoordinates);
const poly = polygon([polygonCoordinates]);
const isInside = booleanPointInPolygon(pt, poly);
if (isInside) {
this.result = '这个点在这个范围内';
} else {
this.result = '这个点不在在这个范围内';
}
</script>
扩展:
打卡成功播放一个音乐提示
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.src = 'https://img.tukuppt.com/newpreview_music/09/04/05/5c8b001d3f57236050.mp3';
innerAudioContext.onPlay(() => {
console.log('开始播放');
});
打卡成功手机震动一下
uni.vibrateLong({
success: function() {
console.log('success');
}
});
经纬度查询: